diff options
author | Jason Molenda <jsm@bugshack.cygnus.com> | 2000-02-07 00:19:45 +0000 |
---|---|---|
committer | Jason Molenda <jsm@bugshack.cygnus.com> | 2000-02-07 00:19:45 +0000 |
commit | 4a0a51e37f1d7dd770d0306310c82c3aaeb8baa7 (patch) | |
tree | 9af57893831870241bb5ce54310653be97a51621 /gdb | |
parent | b7ebfe07f32e9873605d6ff420e63f1c9b627559 (diff) | |
download | gdb-4a0a51e37f1d7dd770d0306310c82c3aaeb8baa7.tar.gz |
Initial revision
Diffstat (limited to 'gdb')
254 files changed, 53472 insertions, 0 deletions
diff --git a/gdb/doc/gdbgui.texinfo b/gdb/doc/gdbgui.texinfo new file mode 100644 index 00000000000..6618f73a30a --- /dev/null +++ b/gdb/doc/gdbgui.texinfo @@ -0,0 +1,411 @@ +\input texinfo @c -*-texinfo-*- +@c Copyright 1988 1989 1990 1991 1992 1993 1994 Free Software Foundation, Inc. +@c +@c %**start of header +@c makeinfo ignores cmds prev to setfilename, so its arg cannot make use +@c of @set vars. However, you can override filename with makeinfo -o. +@setfilename gdb.info +@c +@include gdb-cfg.texi +@c +@ifset GENERIC +@settitle Using the Graphical Interface to @value{GDBN} +@end ifset +@ifclear GENERIC +@settitle Using the Graphical Interface to @value{GDBN} (@value{TARGET}) +@end ifclear +@setchapternewpage odd +@c %**end of header + +@c Since this interface is so new, there is much missing still. +@c Desired but unimplemented features are commented out. + +@iftex +@c @smallbook +@c @cropmarks +@end iftex + +@finalout +@syncodeindex ky cp + +@c readline appendices use @vindex +@syncodeindex vr cp + +@c !!set GDB manual's edition---not the same as GDB version! +@set EDITION 4.13 + +@c !!set GDB manual's revision date +@set DATE January 1995 + +@c THIS MANUAL REQUIRES TEXINFO-2 macros and info-makers to format properly. + +@ifinfo +@c This is a dir.info fragment to support semi-automated addition of +@c manuals to an info tree. zoo@cygnus.com is developing this facility. +@format +START-INFO-DIR-ENTRY +* Gdb: (gdb). The GNU debugger. +END-INFO-DIR-ENTRY +@end format +@end ifinfo +@c +@c +@ifinfo +This file documents the graphical interface to the GNU debugger @value{GDBN}. + + +This is Edition @value{EDITION}, @value{DATE}, +of @cite{Using the Graphical Interface to @value{GDBN}} +for GDB Version @value{GDBVN}. + +Copyright (C) 1994, 1995 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. +@end ifinfo + +@titlepage +@title Using the Graphical Interface to @value{GDBN} +@subtitle The GNU Source-Level Debugger +@ifclear GENERIC +@subtitle (@value{TARGET}) +@end ifclear +@sp 1 +@subtitle Edition @value{EDITION}, for @value{GDBN} version @value{GDBVN} +@subtitle @value{DATE} +@author Stanley T. Shebs +@page +@tex +{\parskip=0pt +\hfill (Send bugs and comments on @value{GDBN} to bug-gdb\@prep.ai.mit.edu.)\par +\hfill {\it Debugging with @value{GDBN}}\par +\hfill \TeX{}info \texinfoversion\par +\hfill doc\@cygnus.com\par +} +@end tex + +@vskip 0pt plus 1filll +Copyright @copyright{} 1994, 1995 Free Software Foundation, Inc. +@sp 2 + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. +@end titlepage +@page + +@ifinfo +@node Top +@top Using the Graphical Interface to @value{GDBN} +@end ifinfo + +This file describes a graphical interface to @value{GDBN}, +the GNU symbolic debugger. + +@node Invocation +@chapter Starting up GUI @value{GDBN} + +If @value{GDBN} has been configured to use the graphical interface, +then you will get the interface automatically upon startup. + +When running as a Unix program and using the X11-based interface, +you must of course be using an X server and/or workstation, +and your @code{DISPLAY} environment variable must be set correctly. +If either of these is not true, then @value{GDBN} will still start up, +but will use only the traditional command interface. + +The exact layout and appearance of the windows will depend on the host +system type. For instance, GDB under Windows will display its windows +inside a larger window, while under Unix/X, each window is a separate +toplevel window. However, general behavior and layout is consistent +across all platforms; omissions or restrictions on particular platforms, +if not documented as unavoidable, should be considered bugs and +reported. + +All GDB windows have a common structure. Each window has an associated +menu bar, which may be at the top of the window or perhaps elsewhere. +Some of the menus and menu items in the menu bar are common to all GDB +windows, while others are specific to particular types of windows. +Below the menu bar is the working data area of the window. If the data +is too large to display all at once, the data area will have scroll bars +on its right and bottom sides. Below the data area are two optional +features; a status/data line, and a button box. + +@section Menus + +@subsection File Menu + +The standard file menu provides operations that affect the overall state +of GDB, mainly file operations, but other things as well. + +About GDB... + +Displays the startup window for GDB. + +File... + +Lets you set the combined executable and symbol file that GDB will use. +(Like "file".) + +Target... + +Brings up a dialog that you can use to connect GDB to a target program. +The dialog is described in more depth later. +(Like "target".) + +Edit... + +Starts up an editor to modify the source file being displayed. + +Exec File... + +Lets you set the executable file that GDB will use. +(Like "exec-file".) + +Symbol File... + +Lets you set the symbol file that GDB will use. +(Like "symbol-file".) + +Add Symbol File... + +Lets you add additional symbol files. +(Like "add-symbol-file".) + +Core File... + +Lets you set the core file that GDB will use. +(Like "core-file".) + +Shared Libraries... + +(Like "sharedlibrary".) + +Quit + +quits GDB. +(Like @samp{quit}.) + + +@c @subsection Commands Menu + +@c The commands menu consists of items that let you run and control the program being +@c debugged. +@c +@c Run +@c +@c Step +@c +@c Next +@c +@c Finish +@c +@c Stepi +@c +@c Nexti + +@subsection Windows Menu + +The windows menu allows access to all the windows available in GDB. +The first part of the menu lists all of the predefined individual windows. +If the window exists already, its item will be marked as such; +selecting the item will cause the window to be put in front if it is +obscured. If it does not exist, then it will be created. + +The second part of the menu lists additional windows that you may have +created, such as source windows or variable displays. + +Command +--- +Source +Assembly +--- +Registers +Variables +--- +Files +@c --- +@c <extra windows> + +@subsection View Menu + +All windows have a view menu, but its contents are highly specific to +window type. For instance, a source window will have a view menu item +to control the display of line numbers, but a register window will instead +have an option to choose the radix in which to display register contents. +You can find the full description of view options with each window type. + +@subsection Help Menu + +The help menu includes access to GDB's online help. + +@section Windows + +@subsection Command Window + +The command window provides access to the standard GDB command +interpreter. In nearly all cases, commands typed into this window +will behave exactly as for a non-windowing GDB. + +Note that not all changes to GDB will be reflected in this window. For instance, +if you were to type a "step" command, then click on the "step" menu item in +the source window, then go back, and type another "step" command, the command +buffer will only show two steps, when you have actually done three. GDB will +put a "..." into the command buffer when operations in other windows are done, +as a reminder that the command buffer is incomplete. + +@c Also note that as a side effect of having the interface and possibly an +@c associated scripting language built in, additional commands may be +@c available. For instance, if tcl is in GDB, the command ``tcl <tcl code>'' +@c will be available. + +The command window has no status line or button box. + +@subsection Files Window + +The files window lists all of the files that were used to build the +executable. + +Clicking on the xxx in the left margin expands/contracts the display of +included files and symbols defined by the file. + +The View menu for this window includes the following items: +Name/Full Pathname +@c Sort by Name +@c Sort by Section&Offset +@c Show All Included Files +@c Included File Indentation... + +@subsection Source Window + +A source window displays a single file of source code. + +The left margin includes an indicator for the current PC, breakpoints and potential breakpoints, +and (optionally) line numbers. + +The View menu for this window includes the following items: +Show Line Numbers +Show Breakdots +@c Jump to PC (if pc changes, scroll back so PC is centered) +@c Tab... (set tabbing) + +@section Extensions + +[description of gdbtk details] + +@c +@c GDBTK Interface Design +@c +@c This is the working document describing the design of the GDBTK +@c interface. Note that overall layout applies only to the default setup; +@c it is expected that debugger users will be able to customize extensively. +@c +@c Default Startup +@c +@c One source window, shows source as in "list main", does *not* set a +@c break at main or run or anything. No current PC indicator, only put +@c in when something runs. +@c +@c Source Window +@c +@c For native, "run" button is always the same, for cross, it's actually +@c a "target" button that pops up appropriate dialog to get connected. +@c Once remote target is active, change button to "run". +@c +@c Be able to toggle assembly interleaved between source. +@c +@c Command Window +@c +@c Is an *optional* window. +@c +@c Behavior mimics command-line GDB running in an Emacs buffer as much +@c as possible. +@c +@c Assembly Window +@c +@c Be able to toggle source interleaved between assembly. +@c +@c Target Info Window +@c +@c Contents similar to "info target". +@c +@c Should expand into process and thread info also. +@c +@c File Info Window +@c +@c Contents similar to "info files". +@c +@c Include data shown in "info sources" as well as "info files". +@c +@c Register Info Window +@c +@c Contents similar to "info registers". +@c +@c Add view option(s) for classes of registers. +@c +@c Stack Info Window +@c +@c Combines backtrace, frame, and local var displays. +@c +@c Signals Dialog +@c +@c Includes all signals whose handling may be controlled, plus +@c checkboxes for what to do with each. +@c +@c Settings Dialog(s) +@c +@c Include all variables that can be "set" and "show"n. +@c +@c General Principles +@c +@c All windows should have a menu that allows access to other windows. +@c Selection of item either brings up for first time or brings to front. +@c +@c All windows should have a "view" menu that controls formatting +@c options for that window. +@c +@c Windows should usually be scrollable. Windows that display largish +@c horizontal things should be horizontal and vertical scrollbars. +@c +@c To do standard modification, add commands or tcl code to .gdbtkinit. +@c +@c Be able to record window positions so they come up in the same way +@c the next time. Could scribble on .gdbtkinit perhaps, or else an +@c aux file that can be sourced by .gdbtkinit. + +@section How to Build + +If GDB is configured with --enable-gdbtk, then upon startup, it will +open windows. + +@node Index +@unnumbered Index + +@printindex cp + +@contents +@bye diff --git a/gdb/gdbtk/ChangeLog-gdbtk b/gdb/gdbtk/ChangeLog-gdbtk new file mode 100644 index 00000000000..a635d673266 --- /dev/null +++ b/gdb/gdbtk/ChangeLog-gdbtk @@ -0,0 +1,7 @@ +Sat Feb 5 00:14:30 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * gdb.rc, gdbtool.ico, README.GDBTK: To here from top level GDB + directory. + * gdb/gdbtcl2: Directory moved to gdbtk/library. + * gdb/gdbtk/generic: New directory. + diff --git a/gdb/gdbtk/README.GDBTK b/gdb/gdbtk/README.GDBTK new file mode 100644 index 00000000000..9f5c0c0b90c --- /dev/null +++ b/gdb/gdbtk/README.GDBTK @@ -0,0 +1,403 @@ + README.GDBTK + Written by Stu Grossman + Updated 9/26/95 by Fred Fish for gdb 4.15 release + Updated 4/18/97 by Martin Hunt + +This file describes how to build, install, use and hack on GDBtk, a TK based +GUI for GDB, the GNU debugger. + +Introduction +============ + +GDBtk is a version of GDB that uses Tcl/Tk to implement a graphical +user inter-face. It is a fully integrated GUI, not a separate +front-end program. The interface consists of several seperate +windows, which use standard elements like buttons, scrollbars, entry +boxes and such to create a fairly easy to use interface. Each window +has a distinct content and purpose, and can be enabled or disabled +individually. The windows contain things like the current source +file, a disassembly of the current function, text commands (for things +that aren't accessible via a button), and so forth. + +Building and installing +======================= + +Building GDBtk is very straightforward. The main difference is that you will +need to use the `--enable-gdbtk' option when you run configure in the top level +directory. You will also need to install Tcl version 7.6 and Tk version 4.2. + +On Unix machines, you will also need to have X11 (R4/R5/R6) installed +(this is a prerequisite to installing Tk). + +For Windows, you can obtain Tcl/Tk from ftp://ftp.smli.com:/pub/tcl/win76p2.exe. +There is a bug in this version of Tcl/tk that requires you to set the +environmental variable TK_LIBRARY to where the tk library directory is installed. +There is also a problem with the colors in images on 16-bit displays under +Windows, so some icons may look strange. + +[See the GDB README file for more details on configure options and such.] + +For example: + + host> cd gdbtk + host> ./configure --enable-gdbtk + host> make + host> make install + +Using GDBtk +=========== + +Just run it like you would a normal GDB (in fact, it's actually called `gdb'). +If everything goes well, you should have several windows pop up. To get going, +hit the start button, and go exploring. + +If you want to use GDB in command line mode, just use the -nw option. Or, you +can undefine the DISPLAY environment variable. + +In the current version, you can have up to 6 windows active at once. They are: + + 1) Command + 2) Source + 3) Assembly + 4) Register + 5) Auto Command + 6) Expression + +Most windows have a similar layout consisting of a menubar, display area, +scrollbar, status box and window-specific buttons. + +The menubar contains the following items: + + File - General file control. Also has window close and quit buttons. + Options - Window specific options. + Window - A menu of other windows that can be popped up or created. + Help - Mostly unimplemented. + +The status box indicates things like the current file and function, or the +current PC and function depending upon the window. + +Command window: + + This can be used to type commands at GDB (useful for when there isn't a + button for what you want to do). + +Source window: + + This contains the current source file. The margin displays line + numbers, and has an indicator for lines that actually contain code (and + therefore can have breakpoints as well). When a breakpoint is set at + that line, the indicator is replaced with a stop sign icon. + + The buttons are: + + Start - Put a breakpoint at main, and then run. + Stop - Stop the program (only active when program is running). + Step, Next, Cont[inue], Finish, Up, Down - Same as the corresponding + GDB command. (Finish runs the current subroutine until it's done.) + Bottom - Does a `frame 0' to put you at the innermost call frame. + + There are also accelerators for various buttons (just type the letter + without any control/meta/alt/shift in the text frame): + + s - Step + n - Next + c - Continue + f - Finish + u - Up + d - Down + + The mouse can also be used to set and clear breakpoints when clicked + in the margin (on a breakpoint indicator). + +Assembly window: + + This displays a disassembly of the current function. It's buttons are + similar to those of the source window, except that it uses Stepi and + Nexti to run one instruction at a time instead of one statement at a + time. The accelerators and mouse actions are also similar. + + Additionally, there is an option to enable mixed source and assembly. + +Register window: + + This displays the registers. It may have to be resized to properly + display all the registers. The displayed registers can be selected + via the Options|Config menu item. + +Auto Command window: + + Using this window, you can specify a command to be executed frequently. + The output will be automatically updated. Options|Accumulate-output + can be used to avoid clearing the window each time so that you can + accumulate a history. + +Expressions: + + The expression window can be used to just calculate an expression, or + to watch the value of an expression (ala the `display' command), using + the Update button. The expression window will also pop up + automatically when an expression is double-clicked in the source window. + +Customizing GDBtk +================= + +There are three primary ways to customize GDBtk. One is to modifiy the +appropriate X resources. The other is to hack a ~/.gdbtkinit file. The last +is to change the files in gdbtcl, which defines the most basic interface +elements. + +X resources give you control over things like the choice of fonts, color +schemes and some geometry info. + +For more serious customizations, you will probably need to hack your +~/.gdbtkinit or gdbtcl files. + +X Resources +=========== + + The class name for GDBtk is `Gdb', and it's appname is `gdb'. The top- +level windows have instance names of `src', 'asm', 'reg', and 'cmd'. The main +display area in each has the class `Text'. So, to change the font in all the +main display areas, something like the following will do: + + Gdb*Text*font: fixed + +To change the font in only the source window: + + Gdb*src*Text*font: fixed + +To find out the names of the widgets do the following (in the command window): + + tk info comm .* + +To get the list of resources (and their classes) for a given widget, do some- +thing like: + + tk .asm.text config + +This will return a list of lists, where each sublist looks something like this: + + {-height height Height 24 25} + +The first item is the name of the config option used when creating the widget. +The second item is the instance name of this resource, the third is the class +name. The fourth item is the default value, and the last item is the current +value. + +To get info about a single resource, add the config option name to the end of +the previous command. Ie: + + tk .asm.text config -font + +will return just the info about the font. + +To find out the class of a window, just do: + + tk winfo class .asm.text + +Note that some things may be explicitly overridden by gdbtk.tcl. In +particular, the `tk colormodel . monochrome' command should probably be +disabled if you want to use color. + +Hacking ~/.gdbtkinit and gdbtcl +================================== +~/.gdbtkinit is sourced at the end of gdbtk.tcl. Currently there is no good +doc on this. See gdbtcl/main.tcl for see what you can change. + +The GUI is primarily implemented by Tcl/Tk code which lives in gdbtcl and a +C file called gdbtk.c. The Tcl/Tk code determines the look and feel, the +layout, and the functions associated with all of the interface elements. The C +code is mostly just glue between GDB internals and Tclland. In essence, all of +the policy is implemented in Tcl/Tk, and is easily changed without recompiling. + +To make more serious changes to the interface, such as adding a new window or +changing the framework, you will have to hack the tcl code. This directory is +installed in $(libdir) (probably /usr/local/lib/). But, you will probably want +to hack on your own private copy before putting it up for the rest of the +users. To find the GDB tcl code, GDB first checks for the environment variable +GDBTK_LIBRARY. This can be a directory name or a list of directories seperated +by colons (semicolons on Windows). GDB will check each directory in order until +it finds "main.tcl". If GDBTK_LIBRARY is not set, GDB will look for +"gdbtcl/main.tcl" in the current directory, and finally, it will try to find +the tcl directory in the sources. + +Note that the old GDBTK_FILENAME environment variable is no longer used. + +Internally, GDBtk is basically GDB, linked with Tcl/Tk, and some glue code that +interfaces GDB internals to Tclland. This means that GDBtk operates as a +single program, not a front-end to GDB. All GDB commands, and a great deal of +the target program state are accessible to the Tcl programmer. In addition, +there are many callbacks from GDB to notify Tclland of important events. + +Here is a brief rundown of the GDB<=>Tcl interfaces: + +Tcl->GDB calls: + gdb_cmd - sends a text command to gdb. Returns the result + gdb_loc - takes PC, and returns a list consisting of a short file name, + the function name, a long file name, the line number and the + PC (in case you didn't supply it). + gdb_sourcelines - Takes a filename, and returns a list of lines that + contain code. + gdb_listfiles - Returns a list of all of the source files. + gdb_stop - Stops the target process. + gdb_regnames - Returns a list of all of the register names. + gdb_fetch_registers - Returns the contents of the specified registers. + gdb_changed_register_list - Returns a list of registers that have + changed since the last call. + gdb_disassemble - Takes a function or PC. Returns the text of a dis- + assembly of the entire function. + gdb_eval - Takes an expression. Returns it's value. + gdb_get_breakpoint_list - Does the obvious. + gdb_get_breakpoint_info - Takes a breakpoint number. Returns a list of + info about that breakpoint. + +GDB->Tcl callbacks: + gdb_tcl_fputs - Sends output into Tcl for the command window. + gdb_tcl_query - Pops up a query window. + gdbtk_tcl_breakpoint - Notifies Tcl of changes to a breakpoint. + gdbtk_tcl_idle - Notifies Tcl that debugged process is now idle. + gdbtk_tcl_busy - Notifies Tcl that debugged process is now running. + +For details, see the usage in gdbtk.tcl, or the definitions in gdbtk.c. + +Additionally, there is a new GDB command `tk', which can be used to poke at +Tk/Tcl from the command window. + +Problems +======== + +During building, you may run into problems with finding Tcl, Tk or X11. Look +in gdb/Makefile, and fix TCL_CFLAGS, TCL, TK_CFLAGS, TK, and ENABLE_CLIBS as +appropriate. + +If you one of the following messages when you run gdb: + + Tcl_Init failed: can't find init.tcl; perhaps you need to + install Tcl or set your TCL_LIBRARY environment variable? +or + Tk_Init failed: can't find tk.tcl; perhaps you need to + install Tk or set your TK_LIBRARY environment variable? + +then you haven't installed Tcl or TK properly. Fix the appropriate environment +variable to point at the {tcl tk}/library directory, and restart gdb. + +If you get the following: + + /usr/local/lib/gdbtk.tcl:1: couldn't read file "/usr/local/lib/gdbtk.tcl": No such file or directory + Stack trace: + can't unset "auto_index": no such variable + while executing + "unset auto_index" + +then GDBtk wasn't installed properly. You can set the GDBTK_FILENAME +environment variable to point at the gdbtk.tcl in your source directory. Note +that the stack trace displayed here is not valid. If you actually get an error +in gdbtk.tcl, the stack trace is useful to pinpoint the location. + +Known Bugs +========== + +generic problems + + o If you open an Assembly window before you have run the program, gdbtk + pops up a dialog box titled "Error in Tcl Script" with the contents + "Error: No function contains the specified address". Trying to then + do other things brings up a dialog box with the contents "Error: + can't read 'current_asm_label': no such variable. + + Solution: Close Assembly window when there is no program running. + + o If you open Registers window before you have run the program, gdbtk + pops up a dialog box titled "Error in Tcl Script" with the contents + "Error: No registers". Trying to then do other things, like use the + Start button to run the program, repeatedly produce the same dialog + box and the action is not performed. + + Solution: Close Registers window when there is no program running. + + o Expressions are sometimes not displayed correctly in the Expression + window. I.E. "argc" works, as does "*(argv+argc)" but not "argv[argc]". + + Solution: None + [ I believe this problem is fixed, but I have not tested it ] + + o The Breakpoint window does not get automatically updated and changes + made in the window are not reflected back in the results from "info br". + I.E. the breakpoint count in the window is not updated at each hit and + enabling/disabling the breakpoint from the Breakpoint window has no effect. + + Solution: Use the command interface to control breakpoints and don't + open a Breakpoint window. + + o Sometimes while an expression window is active you get a dialog box + that complains "Error: invalide command name ".expr.e5.expr" for + example. The Tcl stack trace looks something like: + + invalid command name ".expr.e5.expr" + while executing + "$e.expr get 0.0 end" + invoked from within + "set expr [$e.expr get 0.0 end]..." + (procedure "update_expr" line 17) + invoked from within + "update_expr $expr_num" + invoked from within + "if $expr_update_list($expr_num) { + update_expr $expr_num + . + . + . + + Solution: None except close expression window and reopen it. + + o If you select the "Down" button in either the Source or Assembly + window while in the bottom (innermost) frame, the error message that + results goes just to the command window and may be missed if the + command window is not open. This may also apply to other messages + as well. It should probably put up a notification box instead. + + Solution: Keep Command window open to see error messages. + + o Not really a problem, but it would be nice to have a backtrace + window. + + Solution: Do bt in command window? + + o Also not really a problem, but it might be nice to have a frame/stack + window that displays the last N words on the stack, along with + indications about which function owns a particular frame, how the + frame pointers are chained, and possibly the names of variables + alongside their frame slots. + +m68k-hp-hpux9.00: + + o Attempting to use a Register window results in a Tcl Script Error + "Error: Erroneous arithmetic operation". The Tcl stack trace is: + + while executing + "gdb_fetch_registers $reg_format $regnum" + invoked from within + "set regval [gdb_fetch_registers $reg_format $regnum]..." + ("foreach" body line 2) + invoked from within + "foreach regnum $reg_display_list { + set regval [gdb_fetch_registers $reg_format $regnum] + set regval [format "%-*s" $valwidth $regval] + $win del ..." + invoked from within + "if {$which == "all"} { + set lineindex 1 + foreach regnum $reg_display_list { + set regval [gdb_fetch_registers $reg_format $regnum] + set regval [f ..." + (procedure "update_registers" line 16) + invoked from within + "update_registers all" + . + . + . + + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/gdb.rc b/gdb/gdbtk/gdb.rc new file mode 100644 index 00000000000..9f7c44035a0 --- /dev/null +++ b/gdb/gdbtk/gdb.rc @@ -0,0 +1 @@ +tk ICON DISCARDABLE "gdbtool.ico" diff --git a/gdb/gdbtk/gdbtool.ico b/gdb/gdbtk/gdbtool.ico Binary files differnew file mode 100644 index 00000000000..919202c7f43 --- /dev/null +++ b/gdb/gdbtk/gdbtool.ico diff --git a/gdb/gdbtk/generic/ChangeLog-gdbtk b/gdb/gdbtk/generic/ChangeLog-gdbtk new file mode 100644 index 00000000000..47cc9887edf --- /dev/null +++ b/gdb/gdbtk/generic/ChangeLog-gdbtk @@ -0,0 +1,2655 @@ +Fri Feb 4 23:19:03 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk.c (gdbtk_init): Update default path to tcl code - now + gdbtk/library. + +Fri Feb 4 23:19:03 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * ChangeLog-gdbtk, gdbtk-cmds.c, gdbtk-hooks.c, gdbtk-variable.c, + gdbtk-varobj.c, gdbtk-wrapper.c, gdbtk-wrapper.h, gdbtk.c, + gdbtk.h: Moved here from the top level GDB directory. + +Tue Feb 1 00:17:12 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-hooks.c, gdbtk-variable.c, gdbtk-wrapper.c, + gdbtk-wrapper.h, gdbtk.h: Update to reflect rename of gdb-file / + GDB_FILE to ui-file / ``struct ui_file''. + +2000-01-31 Keith Seitz <kseitz@nwlink.com> + + * gdbtk-cmds.c (gdb_disassemble_driver) If using multi-arch, set the + architecture in the disassembly info. + +Mon Jan 31 18:32:06 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-variable.c, gdbtk-cmds.c, gdbtk.c: Include "tui/tui-file.h" + +1999-09-23 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdbtk-varobj.c (variable_value): Fix small memory leak. + +Mon Jan 3 01:09:24 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (gdb_get_mem): Use builtin_type_int32 et.al. to + force the word size to 32 bits. + +Thu Nov 18 18:19:59 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk.c (tk_command), gdbtk-hooks.c (gdbtk_readline), + gdbtk-variable.c (variable_type): Replace strdup with xstrdup. + +Thu Nov 18 19:03:28 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (gdb_get_mem): Document nbr parameter. Fix check + on nbr and nbytes parameters. + +1999-11-18 Tom Tromey <tromey@cygnus.com> + + * gdbtk-cmds.c (gdb_actions_command): Updated for new + get_tracepoint_by_number. + +Tue Nov 9 15:40:51 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (gdb_get_mem): Keep calling + target_read_memory_partial until all the data is read. + +1999-11-01 Tom Tromey <tromey@cygnus.com> + + * gdbtk-cmds.c (gdb_actions_command): Updated for new + get_tracepoint_by_number. + +Fri Oct 15 18:34:41 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-hooks.c (ui_load_progress_hook): Move extern declaration + to defs.h. + (gdbtk_load_hash): Update SECTION argument to match prototype. + Make static. + +Wed Oct 13 17:57:17 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-hooks.c (gdbtk_flush): Delete. + (gdbtk_add_hooks): Don't initialize flush_hook. + +Mon Oct 11 10:19:04 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (gdb_get_tracepoint_info): Use paddr_nz to convert + the address into a string. + +1999-10-05 James Ingham <jingham@leda.cygnus.com> + + * gdbtk-cmds.c (map_arg_registers): Don't stop at the first + undefined register, but skip it and go on. There may be other + defined registers higher up in the list. + +1999-09-29 Fred Fish <fnf@cygnus.com> + + * gdbtk-varobj.c (variable_create): Replace cast "(CORE_ADDR) - 1" + with the more obviously intended expression "(CORE_ADDR) -1". + +1999-09-23 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdbtk-variable.c (variable_value): Fix handling of baseclasses and + correct the behavior when it is not a baseclass (both cases could + potentially dumping core). + +1999-09-23 James Ingham <jingham@leda.cygnus.com> + + * gdbtk.c (gdbtk_init): Add the initialization of the shell + execute command under cygwin. + + * gdbtk-hooks.c (gdbtk_attach): New function, run from the attach + hook. + (gdbtk_detach): New function, run from the detach hook. + (gdbtk_add_hooks): Add the attach & detach hooks. + +1999-09-23 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdbtk-varobj.c (variable_create): Dynamically allocate variable + object name string. + +1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdbtk-variable.c (_gdb_variable): Remove unused entry. + (variable_update): Fix error in list initialization (apparently + innocuous). + (type_changeable): Fix handling of typedef'ed structs and + unions (removing c_variable.exp test case 2.12 FAIL). + +Mon Sep 20 18:03:28 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-variable.c (new_root_variable): Fix prototype declaration. + * gdbtk.c (_initialize_gdbtk): Add declaration. + * gdbtk-cmds.c (tracepoint_exists): Make static. Add declaration. + * gdbtk.c (gdbtk_add_hooks): Move declaration from here. + * gdbtk.h (gdbtk_add_hooks): To here. + +Fri Sep 17 19:00:39 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c: Include "source.h". + (gdb_load_disassembly): Fix printf calls. + Makefile.in (gdbtk-cmds.o): Add dependency on source.h. + + * gdbtk.c: Include <itk.h> for Itk_Init. + +1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdbtk-varobj.c: New file. It supersedes gdbtk-variable.c and + uses standard gdb varobj code. + +Fri Sep 3 20:16:54 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk.c (gdbtk_init): Cast ``host_name'' and ``target_name'' to + void. While Tcl_SetVar2 treats the value argument as read-only + its prototype does not specify const for the parameter. + +Mon Aug 30 17:56:28 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk.c, gdbtk-hooks.c, gdbtk-cmds.c: #include <unistd.h> moved + to defs.h. + +Mon Aug 30 15:34:42 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-hooks.c (x_event): Missing result to return - return 0. + Make in_x_event volatile. + (in_fputs): Make volatile. + +1999-09-02 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.c: Include version.h, remove inconsistent decls of + host_name and target_name. + +1999-08-27 James Ingham <jingham@leda.cygnus.com> + + * gdbtk.h: Add def'n for gdbtk_fputs, since it is needed outside + of gdbtk-hooks.c + + * gdbtk-cmds.c (gdb_load_disassembly): Really implement this + function. Load the source widget from C. + (gdbtk_load_source): Helper for the above, which loads source lines. + (gdbtk_load_asm): Helper for the above, which loads assembly + lines. + (gdb_restore_fputs): New function, restore the gdbtk_fputs hook, + in case somebody supressed it, and then errored out before they + got a chance to put it back. + +1999-08-10 James Ingham <jingham@leda.cygnus.com> + + * gdbtk-hooks.c: Remove the gdb_disassembly_flavor_hook. Use the + set_hook instead. + +Mon Aug 9 10:28:22 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk.c, gdbtk-cmds.c: Delete #if ANSI_PROTOTYPES code, GDB + assumes ISO-C. + +1999-08-06 Tom Tromey <tromey@cygnus.com> + + * gdbtk-hooks.c (gdbtk_add_hooks): Set `set_hook'. + (gdbtk_set_hook): New function. + +1999-08-05 Keith Seitz <keiths@cygnus.com> + + * gdbtk-variable.c (new_variable): Add missing return value. + +1999-08-02 James Ingham <jingham@leda.cygnus.com> + + * gdbtk-cmds.c: Misc. Cleanups... Mostly wrapping at 80 + characters. + (gdb_loadfile): Go straight to the widget command to insert the + text, rather than through the interpreter. Gives about 2x-3x + speedup in rendering the source text. + (gdb_disassemble): Rewrite to separate out the generic disassembly + work from the printing part. The former goes in + gdb_disassembly_driver. This way I can share the code with the + version that loads the text widget directly. + (gdb_load_disassembly): New function. This will load the text + widget directly (not done yet). + (gdbtk_load_source): Load the text widget with a source line. + (gdbtk_load_asm): Load the text widget with an assembly line. + (gdbtk_print_source): Print a source line to stdout. + (gdbtk_print_asm): Print an assembly line to stdout. + (gdb_disassemble_driver): New function. + + * gdbtk.h: Fix a compiler warning from Keith's 07-27 checkin. + +1999-08-02 Keith Seitz <keiths@cygnus.com> + + * gdbtk-variable.c (CPLUS_FAKE_CHILD): NULL variables are not + "fakes", either. + +1999-07-27 Keith Seitz <keiths@cygnus.com> + + * gdbtk-variable.c: Rewrite. :-) + * gdbtk-wrapper.c (GDB_value_ind): New function. + (GDB_value_slice): New function. + (GDB_value_coerce_array): New function. + (GDB_value_struct_elt): New function. + (GDB_value_cast): New function. + (GDB_get_frame_block): New function. + (wrap_value_slice): New function. + (wrap_value_coerce_array): New function. + (wrap_value_struct_elt): New function. + (wrap_value_cast): New function. + (wrap_get_frame_block): New function. + * gdbtk-wrapper.h: Add declarations for above new functions. + * gdbtk-cmds.c (gdb_selected_block): New function. + (gdb_get_blocks): New function. + (gdb_block_vars): New function. + +1999-07-16 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (gdb_loc): Change all references of "stop_pc" to + "read_pc ()". + + * gdbtk.c (target_is_native): New function. + (target_should_use_timer): Use target_is_native to determine whether + the timer should run. + * gdbtk.h (target_is_native): Add prototype. + * gdbtk-cmds.c (gdb_disassemble): Use target_is_native to determine if + we should disassemble from inferior memory. + +1999-07-09 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * gdbtk-variable.c (variable_obj_command): Add missing comments + for object variable commands. + +Fri Jul 9 12:06:36 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (Gdbtk_Init): Explicitly route log/debug and target + output to stderr instead of stdout. + +1999-06-21 James Ingham <jingham@leda.cygnus.com> + + * gdbtk.c (target_should_use_timer): Add check for "linuxthreads" + to enable the timer for Linux as well as other natives. + +1999-06-15 Keith Seitz <keiths@cygnus.com> + + * gdbtk-hooks.c (gdbtk_annotate_signal): Run + gdbtk_stop_idle_callback so that signals don't interfere + with the stop button. + +1999-06-10 Keith Seitz <keiths@cygnus.com> + + * gdbtk.c (gdbtk_init): Add host_name and target_name to + GDBStartup. + + * gdbtk-cmds.c (gdb_clear_file): Delete breakpoints and + clear the exec file, too. + (gdb_loadfile): Don't close a file that's not opened until + later. + +Wed Jun 9 14:21:40 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (old_regs): Change array to a pointer. + (setup_architecture_data): New function. + (Gdbtk_Init): Call setup_architecture_data. Register ``old_regs'' + as an architecture dependant variable. + +1999-05-25 Keith Seitz <keiths@cygnus.com> + + * gdbtk-wrapper.c (GDB_val_print): Fix compiler warnings. + (wrap_val_print): Ditto. + (GDB_block_for_pc): Ditto. + (wrap_block_for_pc): Ditto. + (GDB_find_frame_addr_in_frame_chain): Ditto. + (wrap_find_frame_addr_in_frame_chain): Ditto. + + * gdbtk-variable.c (variable_create): Rename "-pc" option + to the more explicit name "-frame". Update usage. + (create_variable): Swallow errors before parse_exp_1, too. + If no frame is given as an argument, use the current frame; + otherwise, use the current block in the specified frame. + (variable_children): Check for errors creating children. + (create_child): Ditto. + + * gdbtk-cmds.c (get_selected_frame): New function. + (Gdbtk_Init): Add get_selected_frame to interpreter. + (gdb_get_vars_command): Use current block in selected frame + if no args specified. + + * Makefile.in (gdbtk-cmds.o): Depend on frame.h, too + +Tue May 25 16:12:57 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (REGISTER_CONVERTIBLE, + REGISTER_CONVERT_TO_VIRTUAL): Delete default definitions. + gdbarch.h ensures that there is always a definition available. + +1999-05-20 Andrew Cagney <cagney@b1.cygnus.com> + + Mon Apr 26 09:15:27 1999 Andrew Cagney <cagney@b1.cygnus.com>: + * gdbtk.c (x_event_wrapper): Wrapper for x_event that matches + signal function signature. + (gdbtk_start_timer): set .sa_handler to x_event_wrapper instead of + x_event. + +1999-05-14 Keith Seitz <keiths@cygnus.com> + + * configure.in (ENABLE_GDBTK): Don't clobber WIN32LIBS. + * configure: Regenerated. + +1999-04-12 Keith Seitz <keiths@cygnus.com> + + * gdbtk-variable.c (variable_value_changed): Swallow errors from + evaluate_expression. + +1999-04-09 James Ingham <jingham@cygnus.com> + + * gdbtk-cmds.c (gdb_get_mem): Use the Tcl list API to add the + ASCII entry to the return list. We were trying to do the quoting + by hand which is bound to lose in some cases. + +1999-04-06 Martin Hunt <hunt@cygnus.com> + + * gdbtk-hooks.c (gdbtk_annotate_signal): New function. + Notifies GDBtk when a signal occurs. + +1999-04-02 Keith Seitz <keiths@cygnus.com> + + * gdbtk-hooks.c (gdbtk_force_detach): New global. + (x_event): Change to return gdbtk_force_detach so that + callers will know if we want to detach. See comments. + (gdbtk_wait): Insert calls to gdbtk_start/stop_timer. This + is a nop for most hosts/targets. Remove ice-specific code. + + * gdbtk-cmds.c (gdb_stop): Add "detach" option, which forces + gdb to detach from the target. See comments. + + * gdbtk.c (target_should_use_timer): New function. + (gdbtk_start_timer): Only use on unix native targets. + (gdbtk_stop_timer): Ditto. + + * gdbtk.h (x_event): Update declaration: now returns an int. + +1999-03-29 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.c, gdbtk-cmds.c, gdbtk-hooks.c: Don't include setjmp.h. + +1999-03-29 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (pc_function_name): New function which returns the + source name (regardless of mangling) of the function at a given PC. + (gdb_get_function_command): Use it. + (gdb_get_tracepoint_info): Ditto. + (gdb_loc): Ditto. + (gdb_get_breakpoint_info): Ditto. + + * Makefile.in (install-only): Don't install help/index.toc: it doesn't + exist anymore. + +Wed Mar 10 19:37:23 1999 Geoffrey Noer <noer@cygnus.com> + + * gdbtk-cmds.c: Don't need to include any Win32 API headers. + * gdbtk-hooks.c: Include Windows.h, not just winuser.h. + * gdbtk.c: Ditto. + +1999-03-04 Martin Hunt <hunt@cygnus.com> + + * gdbtk-hooks.c (gdbtk_load_hash): Change download_hash() + to Download::download_hash(). + +1999-03-01 Martin Hunt <hunt@cygnus.com> + + * gdbtk.c (TclDebug): Increase buffer size to 10000, in case + backtraces are very long. + +1999-02-26 James Ingham <jingham@cygnus.com> + + * gdbtk-cmds.c (gdb_search): Add a -filename switch, which returns + the file in which the function or type was defined, along with the + function... + + * gdbtk.c (gdbtk_find_main): The external editor stuff was getting + set twice... + +1999-02-18 Martin Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_disassemble): When debugging native threads, + set disassemble_from_exec to 0. This fixes bugs where disassembly + of threaded programs failed. + +1999-02-16 James Ingham <jingham@cygnus.com> + + * gdbtk.c (gdbtk_init): Remove redundant setting of the external + editor variables. + +1999-02-11 Martin Hunt <hunt@cygnus.com> + + * gdbtk-variable.c (variable_format): Enable binary format. + +1999-02-11 Martin Hunt <hunt@cygnus.com> + + * gdbtk-hooks.c: Change ALL Tcl_Eval calls in hooks to + call report_error() if there are errors. + +1999-02-11 Martin Hunt <hunt@cygnus.com> + + * gdbtk.c, gdbtk-cmds.c, gdbtk-hooks.c: Removed old IDE stuff. + +1999-02-09 Martin Hunt <hunt@cygnus.com> + + * gdbtk-hooks.c: Remove gdbtk_ignorable_warning prototype. + It is in gdbtk.h. + (report_error): New function. Displays debugging information + if a hook function fails. All hook functions should probably + call this. + (gdbtk_warning): Call report_error() if there is a problem. + (gdbtk_register_changed): Call report_error() if there is a problem. + (gdbtk_memory_changed): Call report_error() if there is a problem. + (gdbtk_ignorable_warning): Pass along class argument. If there + is a problem, call report_error(). + + * gdbtk-cmds.c: Remove TclDebug prototype. It is in gdbtk.h. + (gdb_loadfile): Add class name to gdbtk_ignorable_warning call. + + * gdbtk.c (TclDebug): Add "priority" argument. Calls "dbug" + instead of "debug". Removed non-ANSI ifdefs. + + * gdbtk.h: Fixed protos for gdbtk_ignorable_warning and TclDebug. + +1999-02-05 James Ingham <jingham@cygnus.com> + + * Makefile.in: Add GDBTK_CFLAGS - this is now used to hold + -fwritable-strings when compiling with Tk8.1. + * configure.in: Add GDBTK_CFLAGS, set it to -fwritable-strings for + Tcl/Tk8.1 & greater. + * acinclude.m4: Move the rest of the defines to find Itcl, Itk & + Tix from aclocal.m4 to here. + * aclocal.m4: regenerate. + * configure: regenerate. + + * gdbtk-hooks.c (x_event): Tcl_ObjGetVar2 was removed from + Tcl8.1. Use Tcl_GetVar2 instead. + * gdbtk-hooks.c (gdbtk_trace_find): Fix up call to + Tcl_GlobalEvalObj for Tcl/Tk 8.1. + * gdbtk-hooks.c (gdbtk_trace_start_stop): Call to Tcl_EvalObj was + inefficient, replace with call to Tcl_GlobalEval. + * gdbtk.c: Don't swap out the Tcl_Alloc calls in gdbtk.c. We took + care of that in Tcl itself for 8.1. + * gdbtk.c: Remove const from the script string since Tcl8.1 has + taken to scribbling sentinals into strings passed to it again... + + * gdbtk-cmds.c (wrapped_call): Change declaration of 1st arg from + char * to PTR to eliminate warning. + * gdbtk-cmds.c (perror_with_name_wrapper): Ditto + +Thu Feb 4 10:35:28 1999 Keith Seitz <keiths@cygnus.com> + + * gdbtk-variable.c (variable_create): Allocate enough + space to hold the NULL, too! + +Wed Feb 3 13:37:07 1999 Keith Seitz <keiths@cygnus.com> + + * gdbtk-variable.c (variable_create): Add parentheses to the name + so that casts do not confuse the expression parser. + +1999-02-03 Keith Seitz <keiths@cygnus.com> + + * gdbtool.ico: Add missing desktop image. + +1999-02-02 Martin Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (get_register): For RAW display, concat all the + pieces together before calling fputs. + +1999-02-01 Martin Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c: (gdb_set_bp): Change the "type" argument + to be ASCII instead of an integer. Currently accepts "temp" + or "normal". Fixed error messages. + (gdb_set_bp_addr): Ditto. + +1999-01-29 James Ingham <jingham@cygnus.com> + + * gdbtk.c (gdbtk_init): Set the fputs_unfiltered_hook to + gdbtk_fputs BEFORE you eval script. The old code was setting it + to null until after you did this, but that is wrong, because it + will cause the output of CAUGHT errors to go to gdb_stderr, which + is wrong. You only want to write errors to the console if the + eval generates an error. + +1999-01-29 Martin Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_get_breakpoint_info): When printing addresses, + do not rely on the format string "%lx" -- it does not exist for all + hosts. Use paddr instead. + (gdb_loadfile): Increase maximum line size to pass testsuite cases. + + * gdbtk-hooks.c (gdbtk_add_hooks): Remove pc_changed_hook and + add register_changed_hook and memory_changed_hook. + (gdbtk_register_changed): New function. + (gdbtk_memory_changed): New function. + + * gdbtk.c (gdbtk_init): Create tcl warp_pointer command + for use with testing. + + * gdbtk-cmds.c (gdb_loc): Fix for case where there are only + minimal symbols. Also make gdb_loc return the shared library + the location is in, if it is in one. + +1999-01-27 James Ingham <jingham@cygnus.com> + + * gdbtk-wrapper.c: Missed a couple of places where FILE->GDB_FILE + in the fputs_unfiltered_hook needed to propagate. + +1999-01-27 James Ingham <jingham@cygnus.com> + + Merging in changes from gdbtk-980810 - the Itcl3 + gdb branch. + + 1999-01-12 Martin Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_loadfile): Increase maximum line size so + files with very long lines get numbered correctly. + + Thu Jan 7 06:50:32 1999 Keith Seitz <keiths@cygnus.com> + + * gdbtk-hooks.c (gdbtk_add_hooks): Add the error_begin_hook; + (gdbtk_error_begin): New function. + (gdbtk_fputs): If GDBTK_ERROR_ONLY is set, treat output to + any stream as if it had come from gdb_stderr. + + * gdbtk.h: Define GDBTK_SYMBOL_SOURCE_NAME: does the same thing + as SYMBOL_SOURCE_NAME, except that it NEVER returns a mangled name. + Define GDBTK_ERROR_ONLY flag for result_ptr. + + * gdbtk-cmds.c (gdb_listfuncs): Use SYMBOL_DEMANGLED_NAME to + get the symbol's fully demangled name (including class and + args for overloaded funcs), not cplus_demangle. + (get_frame_name): Use GDBTK_SYMBOL_SOURCE_NAME to get the name + of the frame level. + + * gdbtk-wrapper.c, gdbtk-wrapper.h: + (GDB_val_print): Allow caller to specify all function args to val_print. + (wrap_val_print): Ditto. + + * gdbtk-variable.c (variable_value): Clear addressprint when getting + value of C++ reference-type variables + If we errored because a parent (struct pointer) was junk, output + an error message indicating so. + (call_gdb_val_print): Tell val_print to dereference C++ reference + types. + (number_of_children): void * also has no children. + (get_call_output): Clear any error flags that may have been set + as a result of error_begin. + + * utils.c (error_begin_hook): New hook. + (error_begin): Call error_begin_hook so that the GUI + gets notified. + + * defs.h (error_begin_hook): Declare. + + Wed Jan 6 08:43:31 1999 Keith Seitz <keiths@cygnus.com> + + * gdbtk-wrapper.c, gdbtk-wrapper.h: Add wrappers for parse_exp_1, + evaluate_type, block_for_pc, block_innermost_frame, reinit_frame_cache, + and find_frame_addr_in_frame_chain. + + * gdbtk-variable.c (variable_create): Check for failure when + creating variables. + (create_variable): Use wrapped calls for block_for_pc, parse_exp_1, + and block_innermost_frame. + Return NULL if parse_exp_1 fails. + Attempt to prohibit creating a gdb_variable for type names. + (variable_value_changed): Use wrapped calls for reinit_frame_cache and + find_frame_addr_in_frame_chain. + (variable_type): Use wrapped call for evaluate_type. + (variable_value): Use wrapped call for parse_exp_1. + (variable_editable): Use wrapped call for evaluate_type. + + Tue Jan 5 11:37:17 1999 Keith Seitz <keiths@cygnus.com> + + * gdbtk-variable.c: New variable object interface. + * gdbtk-wrapper.c, gdbtk-wrapper.h: New wrappers for safely calling + gdb functions without the fear of longjmp'ing. + * configure.in (CONFIG_OBS): Add gdbtk-wrapper.o and gdbtk-variable.o + when gdbtk is enabled. + * configure: Regenerate. + * Makefile.in: Add gdbtk-wrapper.o and gdbtk-variable.o + * gdbtk-cmds.c (call_wrapper): Export so that other files can use. + (Gdbtk_Init): Initialize new variable interface. + * gdbtk.h: Add declaration for call_wrapper. + + Tue Jan 5 11:19:14 1999 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (gdb_loc): Call resolve_sal_pc to before using + the sal's pc. + + * gdbtk.c (gdbtk_init): Add global array GDBStartup to interpreter + which contains any startup info. Add "inhibit_prefs" (follows -nx) + so that "-nx" turns preference reading/writing off. + + Mon Dec 21 11:11:02 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (get_register): Call get_saved_register instead of + read_relative_register_raw_bytes to fetch registers. + + Thu Dec 17 09:00:56 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (gdb_search): Don't mention C++ RTTI and + global constructor/destructor symbols. + + Thu Nov 12 15:20:15 1998 Jim Ingham <jingham@cygnus.com> + * More bug fixes merged in from devo. + + * gdbtk-cmds.c (gdb_cmd): Added an optional second argument to the + gdb_cmd, which is from_tty. This is passed to the gdb command + parser. It is 0 by default, and the console window passes 1. + + * gdbtk-cmds.c: moved disassemble_from_exec from gdbtk.c to gdbtk-cmds.c + with all the other link-var'ed variables + + * gdbtk-hooks.c (gdbtk_trace_find): Only run the hook functions if + we are called from_tty. + + * gdbtk-hooks.c (gdbtk_trace_start_stop): Set the trace buttons + from a trace_start_command callback rather than doing it as a + special case in gdb_cmd. + + * tracepoint.c (tstart_command, tstop_command): Add call to + trace_start_stop_hook here. + + 1998-11-04 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_set_bp_addr): For callback, send full + pathname instead of just basename. + + 1998-11-03 Keith Seitz <keiths@cygnus.com> + * v850ice.c (do_gdb): New function. + (ice_stepi): Use do_gdb to step properly. + (ice_nexti): Use do_gdb to step properly. + (view_source): Correct call to src window's location for new version. + + Tue Aug 25 18:13:30 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk.c (gdbtk_init): I hadn't excised ALL the old startup code, + so it was not working correctly. Now it does. + + Fri Aug 21 14:37:40 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk.c (gdbtk_init): Changed the startup code to use + tcl_findLibrary + + + + +on Dec 28 17:44:36 1998 David Taylor <taylor@texas.cygnus.com> + + + The following changes were made by Jim Blandy <jimb@cygnus.com>, + Edith Epstein <eepstein@cygnus.com>, Elena Zannoni + <ezannoni@cygnus.com> Stan Shebs <shebs@cygnus.com>, and David + Taylor <taylor@cygnus.com>, as part of the project to merge in + changes originally made by HP; HP did not create ChangeLog + entries. + + * gdbtk.c (gdbtk_init): change stderr to gdb_stderr. + + * gdbtk-cmds.c + (get_pc_register): Use paddr_nz, not sprintf's %llx and + a cast to `long long'. Those aren't portable. + (gdb_eval): add embedded_offset param to val_print call + (get_register): add embedded_offset param to val_print call + + * gdbtk-hooks.c + (tk_command_loop): change instream to a FILE. + (gdbtk_flush): change both the declaration and definition to + use GDB_FILE rather than FILE. + +Mon Dec 21 11:11:02 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (get_register): Call get_saved_register instead of + read_relative_register_raw_bytes to fetch registers. + +Thu Dec 17 09:00:56 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (gdb_search): Don't mention C++ RTTI and + global constructor/destructor symbols. + +Tue Dec 15 10:09:31 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c (gdb_disassemble): Fix typo. + +Sun Dec 13 09:52:51 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk-cmds.c: Update TARGET_PRINT_INSN_INFO, TARGET_PRINT_INSN. + +Fri Dec 11 09:52:04 1998 Andrew Cagney <cagney@chook> + + * gdbtk-cmds.c: Replace reg_name with REGISTER_NAME. + +Mon Dec 14 13:20:50 1998 Jim Ingham <jingham@cygnus.com> + + * Makefile.in, configure.in configure - add support for LIBGUI + outside the IDE context. + +Thu Nov 19 13:14:57 1998 Geoffrey Noer <noer@cygnus.com> + + * gdbtk-cmds.c: Can't start using new API names yet. Switch back + to calling cygwin32_ funcs until some time has passed... + * gdbtk.c: Ditto. Also, include sys/cygwin.h for Cygwin, instead + of providing own proto. + +Fri Nov 13 00:15:08 1998 Geoffrey Noer <noer@cygnus.com> + + Changes to account for name change from cygwin32 to cygwin and + clean up Win32-related ifdefs. + + * gdbtk.c: lose "32" from cygwin_ func calls. ifndef for + checking DISPLAY should be for _WIN32, not WINNT. + * gdbtk.h: pick GDBTK_PATH_SEP based on _WIN32, not WINNT. + * gdbtk-cmds.c (gdb_path_conv): lose "32" from cygwin_ func call, + change ifdef to __CYGWIN32__ instead of WINNT. + * {gdbtk.c, gdbtk-hooks.c}: __CYGWIN32__ refs drop the "32". + +Thu Nov 12 15:20:15 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk-cmds.c (gdb_cmd): Added an optional second argument to the + gdb_cmd, which is from_tty. This is passed to the gdb command + parser. It is 0 by default, and the console window passes 1. + + * gdbtk-cmds.c: moved disassemble_from_exec from gdbtk.c to gdbtk-cmds.c + with all the other link-var'ed variables + + * gdbtk-hooks.c (gdbtk_trace_find): Only run the hook functions if + we are called from_tty. + + * gdbtk-hooks.c (gdbtk_trace_start_stop): Set the trace buttons + from a trace_start_command callback rather than doing it as a + special case in gdb_cmd. + + * tracepoint.c (tstart_command, tstop_command): Add call to + trace_start_stop_hook here. + +Wed Nov 4 12:41:42 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk-cmds.c (gdb_set_bp_addr): Pass the type, enable & thread + to gdbtk_tcl_breakpoint. + * gdbtk-hooks.c (gdbtk_trace_find): Added this function. It is + the hook function for tfind commands. + * tracepoint.c (trace_find_command): Added the trace_find_hook, + run when you do trace_find_command. + * tracepoint.h: Define the trace_find_hook. + +1998-11-03 Keith Seitz <keiths@cygnus.com> + + * v850ice.c (do_gdb): New function. + (ice_stepi): Use do_gdb to step properly. + (ice_nexti): Use do_gdb to step properly. + (view_source): Correct call to src window's location for new version. + +Mon Nov 2 11:16:10 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk-cmds (gdb_get_tracepoint_info): Demangle C++ function names. + +Fri Oct 30 11:22:23 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk-cmds (gdb_get_tracepoint_info): Fixed typo. + +Wed Oct 28 16:19:02 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_set_bp_addr): For callback, send full + pathname instead of just basename. + +Wed Oct 28 10:14:33 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk-cmds.c: Made the bdtypes & bpdisp arrays shared so they + could be used in gdbtk-hooks.c (breakpoint_notify). + Also fixed a few error messages to actually print the bp number + rather that #%d... + * gdbtk-hooks.c (breakpoint_notify): pass more of the information + about the breakpoint into the Tcl command, so it does not have to + try and guess about information we have on the C side. + * gdbtk.h: Export the bptypes & pbdisp arrays. + +1998-10-13 Jason Molenda (jsm@bugshack.cygnus.com) + + * gdbtk.c, gdbtk-cmds.c: Cast parameters passed to make_cleanup to + use the new make_cleanup_func typedef. + +1998-10-08 Keith Seitz <keiths@cygnus.com> + + * gdbtk-hooks.c (gdbtk_add_hooks): Install a hook for + (new) file_changed_hook. + (gdbtk_exec_file_changed): Rename to gdbtk_exec_file_display + to mimic hook's name. + (gdbtk_file_changed): New hook function. + +Tue Oct 6 22:57:13 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure.in (links): Link gdbtcl2 directory instead of gdbtcl. + +Mon Oct 5 00:34:00 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_set_bp_addr): New command. Sets a + breakpoint at an address. Use this instead of gdb_cmd "break" + because the syntax of the break command is broken and doesn't + allow you to create a thread-specific BP at an address. Also + this is faster. + +Sun Oct 4 22:35:47 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_set_bp): Add an optional thread number. + (gdb_find_bp_at_line): New function. Returns a list of bpnums + at the specified line number. + (gdb_find_bp_at_addr): New function. Returns a list of bpnums + at an address.. + +1998-10-02 Keith Seitz <keiths@cygnus.com> + + * gdbtk-hooks.c (gdbtk_exec_file_changed): New function which handles + exec_file changes. + (gdbtk_add_hooks): Define exec_file_display_hook (to gdbtk_exec_file_changed) + + * gdbtk-cmds.c (gdb_stop): target_stop is ALWAYS defined, so + compare against something a little more meaningful (target_ignore). + +1998-09-24 Keith Seitz <keiths@cygnus.com> + + * gdbtk.c (gdbtk_wait): Don't run the timer for ice targets. + + * v850ice.c (WM_ADDR_TO_SYM): New message. + (v850ice_wndproc): Add handler for WM_SOURCE. + (v850ice_wait): Call the ui_loop_hook occasionally. + (ice_cont): Acknowledge message before doing anything. + (ice_stepi): Ack message and let gdbtk do stepping. + (ice_nexti): Ack message and let gdbtk do stepping. + (view_source): New function ICE calls to display source code. + +1998-09-18 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (get_frame_name): Demangle function names, too. + +Thu Sep 10 22:10:29 1998 Jim Ingham <jingham@cygnus.com> + + *gdbtk-cmds.c (gdb_disassemble): Make sure the symtab's linetable is not + null before trying to use it... + +1998-09-02 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (gdb_cmd): Do not run the timer when downloading -- + the ui_progress_hook that has been installed will actually + update the gui for us. + +Mon Aug 31 15:42:10 1998 Tom Tromey <tromey@cygnus.com> + + * gdbtk-hooks.c (context_hook): Don't define. + +1998-08-31 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (gdb_listfuncs): When stripping out "global destructors" + and "global constructors", do not append any elements to the result. + +Sun Aug 30 00:49:18 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (Gdbtk_Init): Link C variable gdb_context + with tcl variable gdb_context_id. + + * gdbtk-hooks.c (gdbtk_context_change): Implement new hook called + context_hook. Called when threads change. + + * gdbtk.c: Initialize gdb_context. + + * gdbtk.h: Declare gdb_context. + + * infrun (wait_for_inferior): Call context_hook. + + * thread.c (thread_command): Call context_hook. + + * defs.h: Declare context_hook. + +Fri Aug 28 12:14:49 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_loadfile): Open the file after doing + the symtab lookup and calling symtab_to_filename(). This + makes GDBtk work with the GDB "dir" command. + +1998-08-18 Keith Seitz <keiths@cygnus.com> + + * gdbtk-hooks.c (gdbtk_add_hooks): Set selected_frame_level_changed_hook. + (gdbtk_selected_frame_changed): New function. + + * gdbtk-cmds.c (Gdbtk_Init): Add command gdb_stack into interpreter. + Link gdb's global selected_frame_level with interpreter global + gdb_selected_frame_level. + (gdb_stack): New function to faciltate speedier backtraces from + gdbtk. + (get_frame_name): New helper function for gdb_stack. + +Tue Aug 18 15:42:40 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_listfuncs): Strip out global constructors + and destructors from the function list. + +Thu Aug 13 15:09:59 1998 Drew Moseley <dmoseley@cygnus.com> + + * gdbtk.c (gdbtk_cleanup): added a scope-level around the contents + of the #ifdef so that the variable declarations in there would not + be illegal in a C compilation. + +Mon Jul 27 13:07:16 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_call_command): Removed because it is now + in gdbtk-hooks.c + (null_routine): Removed. + + * gdbtk-hooks.c (tracepoint_notify): Fix sprintf to + match number of arguments. + + * gdbtk-cmds.c (gdb_loc): When calling gdb_loc with an + argument, call find_pc_line() to get a complete + symtab_and_line struct. + +Fri Jul 24 14:25:43 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk-cmds.c (gdb_search): Add missing NULL to switches. + Add missing flags to result_ptr. + Pass along any errors caused by getting the list of files from + tcl. + Allocate correct amount of memory for the file list. + Don't do any unecessary cleanups. + +Fri Jul 24 01:08:37 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk-cmds.c (gdb_loadfile): When there are no + linenumbers, use only one tab. + +Sat Jul 18 12:28:39 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_cleanup): Add call to tcl function + gdbtk_cleanup. We need this so the GUI gets to clean + up no matter how GDB exits. + +Wed Jul 1 13:10:58 1998 Jim Ingham <jingham@cygnus.com> + + * Moved gdbtk_hooks.c & gdbtk_cmds.c to gdbtk-hooks.c & + gdbtk-cmds.c to comply with the gdb conventions. Changed the + configure & makefile to reflect the change... + +Wed Jul 1 11:07:21 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk.c: removed all the commands and hooks from this file so + now it contains only the startup code. + * gdbtk.c (gdbtk_init): Fixed a bug in the startup code on Windows + that caused gdbtk not to find the share directory unless + GDBTK_LIBRARY was set. + * gdbtk_cmds.c: New file - this contains all the Tcl commands that + gdb defines. All the old commands were moved here, the + string-based commands were converted to object commands, and the + object-based commands were all converted to uniformly use the + call_wrapper. A new function, Gdbtk_Init was added to centralize + initializing the gdb package. + * gdbtk_hooks.c: New file - All the hooks were moved here, and a new + function, gdbtk_add_hooks was added to centralize adding all these + hook functions. gdbtk_fputs was also modified to handle the new + result_ptr structure. See the comments in gdbtk.h for more + details. + * gdbtk.h: New file - this contains all the defines and globals + shared by gdbtk.c, gdbtk_cmds.c & gdbtk_hooks.c + * Makefile.in, configure.in & configure: mutatis mutandi for the + new files. + + +Mon Jun 29 11:49:17 1998 Keith Seitz <keiths@cygnus.com> + + * main.c (main): Don't include gdbtk test code if GDBTK is + not defined by configure. + + * configure.in: When enabling gdbtk, add "-DGDBTK" to ENABLE_CFLAGS. + + * configure: Regenerate. + +Fri Jun 26 13:56:07 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk.c: Change all references to static global "interp" to + "gdbtk_interp" and export this global. + (gdbtk_init): If gdbtk_source_filename is not NULL, source this file + into the interpreter when it goes idle. + Add new command "gdb_search". + (gdb_search): New function which searches the symbol table. + (gdbtk_test): New function called by main when the --tclcommand + option is used. + + * main.c (main): Add a new option "--tclcommand" which is used + by the testsuite to source a file into the interpreter when it + goes idle. + +Sun Jun 21 09:31:12 1998 Ron Unrau (runrau@cygnus.com) + + * gdbtk.c (gdb_set_bp): Use new interface. + +Wed Jun 17 19:12:23 1998 Jeff Holcomb <jeffh@cygnus.com> + + * Makefile.in (install-only): Install tracing help files. + +Mon Jun 15 13:18:21 1998 Jim Ingham <jingham@cygnus.com> + + * gdbtk.c (gdbtk_init): Add elements to the auto_path AS LIST + ELEMENTS. This allows gdbtk to work when installed in a directory + which has a space in the path. D. Moseley pointed out the bug. + + +Tue Jun 9 14:10:46 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk.c (gdb_get_vars_command): Return static variables and + variables stored in registers. + + * main.c (main): Call pre/post_add_symbol_hook's when loading + executables and symbol files. + +Fri Jun 5 00:16:22 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_init): Change all references to + GDBTK_IDE to IDE_ENABLED. + +Thu Jun 4 18:31:53 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_init): Initialize tkTable. + +Thu Jun 4 10:15:03 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * gdbtk.c: merged: + + - Elena Zannoni <ezannoni@kwikemart.cygnus.com> + (call_obj_wrapper): in case of error, copy the + error message from the result to the error_string. + (gdbtk_fputs): add comments. + (gdb_actions_command): call validate_actionline when installing the + tracepoint, to do the syntax checking of the actions for us. + - Elena Zannoni <ezannoni@kwikemart.cygnus.com> + (gdb_get_trace_frame_num): new function to get the + trace frame number from gdb. + (gdbtk_init): added new command gdb_get_trace_frame_num. + - Jim Blandy <jimb@zwingli.cygnus.com> + (struct wrapped_call_objs): Change the `func' member to + be a Tcl_ObjCmdProc, not an Tcl_CmdProc, since it accepts a vector + of objects as arguments. Change the object vector to be const, + since that's what all the users of this structure seem to expect. + (call_obj_wrapper): Cast clientData properly before storing it in + the wrapped_args structure. + +Thu May 28 17:19:14 1998 Keith Seitz <keiths@cygnus.com> + + * gdbtk.c (_initialize_gdbtk): Get rid of the console. Patch from + Chris Faylor (cgf@cygnus.com). + + * configure.in: Link cygwin32 with subsystem console. + + * configure: Regenerated + +Sun May 24 14:00:24 1998 Keith Seitz <keiths@cygnus.com> + + * ser-unix.c (wait_for): Do not reset timeout_remaining for cygwin32 so that + we can use this member to track real timeouts. + (hardwire_readchar): Modify for cygwin32 so that we only ever use a real + system timeout of one second. Track the "real" timeout as a series of these + one second timeouts. + Call ui_loop_hook to keep the gui alive. + + * top.c: Define new hook for cygwin32, "ui_loop_hook". + + * gdbtk.c (gdbtk_init): Add ui_loop_hook for CygWin32 to work around + update problems. + +Thu May 21 13:56:24 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * gdbtk.c: reinserted the changes that were accidentally deleted: + (_initialize_gdbtk): Use correct device names in + cygwin-specific call (cosmetic change). + (gdbtk_ignorable_warning): removed va_list parameter, + which was unused. + (_initialize_gdbtk): add cygwin32 specific code to + allow `gdb -nw' to work when specified specified from a windows + console-mode command line. + +1998-05-19 Jim Blandy <jimb@zwingli.cygnus.com> + + * gdbtk.c (struct wrapped_call_objs): Change the `func' member to + be a Tcl_ObjCmdProc, not an Tcl_CmdProc, since it accepts a vector + of objects as arguments. Change the object vector to be const, + since that's what all the users of this structure seem to expect. + (call_obj_wrapper): Cast clientData properly before storing it in + the wrapped_args structure. + +Wed May 13 11:12:58 1998 James Ingham <jingham@leda.cygnus.com> + + * gdbtk.c: Fixed a goof in the definition of the gdb_get_args & + gdb_get_locals Tcl commands. Moved the previous ChangeLog entry + from ChangeLog to ChangeLog-gdbtk (here)... + +Tue May 12 13:29:20 1998 Jeff Holcomb <jeffh@cygnus.com> + + * Makefile.in (install-only): Add images/icons.txt and + images2/icons.txt to files that need to be installed. + +Tue May 12 12:03:16 1998 James Ingham <jingham@leda.cygnus.com> + + * gdbtk.c: Add an object call wrapper for the new Tcl_Obj based + commands. This way the obj commands will also go through + catch_errors. This is just a bandaid while I rewrite the + string-based commands to use the object format. + +Tue May 5 09:30:25 1998 Christopher Faylor <cgf@cygnus.com> + + * gdbtk.c (_initialize_gdbtk): Use correct device names in + cygwin-specific call (cosmetic change). + +Wed Apr 29 15:53:16 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * gdbtk.c (gdbtk_ignorable_warning): removed va_list parameter, + which was unused. + +Tue Apr 28 19:41:33 1998 Tom Tromey <tromey@cygnus.com> + + * Makefile.in (GDBTKLIBS): New macro. + (INSTALLED_LIBS): Include GDBTKLIBS. + (CLIBS): Likewise. + * configure: Rebuilt. + * configure.in: Put Tcl/Tk libs into GDBTKLIBS, not LIBS. + (GDBTKLIBS): AC_SUBST. + +Thu Apr 23 19:01:05 1998 Keith Seitz <keiths@onions.cygnus.com> + + * Makefile.in (install-only): Install help files. + +Wed Apr 22 21:17:35 1998 Christopher Faylor <cgf@cygnus.com> + + * gdbtk.c (_initialize_gdbtk): add cygwin32 specific code to + allow `gdb -nw' to work when specified specified from a windows + console-mode command line. + +Wed Apr 15 11:23:53 1998 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtcl: Remove directory and contents, this version of + the interface is obsolete. + +Mon Apr 13 16:17:52 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_loadfile): Change fstat() call to stat(). + Needed because you can't convert a FILE* to an fd. + +Mon Apr 13 16:28:07 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * gdbtk.c: (perror_with_name_wrapper) new function to call + perror_with_name safely. + (gdb_loadfile) added source vs. executable time stamp check. + (gdbtk_warning) new function to pass a warning message to the gui. + (gdbtk_ignorable_warning) new function to pass a warning + to the gui. Used only for the src. vs. exec check. + (gdbtk_init) added warning_hook + added include <sys/stat.h> + +Mon Apr 13 12:58:26 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdbtk_start_timer): Include on all platforms. Decrease + timer interval a little. + (gdbtk_stop_timer): Include on all platforms. + (gdbtk_wait): No more signals! Use a timer on all platforms to keep the + GUI alive. + (gdbtk_init): Remove FIOASYNC and all x_fd references. Now using timers + on all platforms. + +Fri Apr 10 15:48:10 1998 Jason Molenda (crash@bugshack.cygnus.com) + + * gdbtk.c (gdb_listfiles): Allocate space for 'files' dynamically. + +Thu Apr 9 14:20:59 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_init): Remove redundant variable "IDE". + +Tue Apr 7 15:13:58 1998 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.tcl: Remove, no longer used. + +Tue Apr 7 12:49:45 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_cmd): NEVER call the busy, update, and idle hooks. + +Tue Mar 31 15:42:06 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_loadfile): Don't use the return result from + sprintf, which returns a char * under SunOS4. + +Tue Mar 31 17:18:43 1998 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Add $(LIBIDETCL) as well as $(LIBIDE) if + --enable-ide. + * Makefile.in (IDE_CFLAGS_X): Add -I for libidetcl/src. + (LIBIDETCL): Define. + * configure: Rebuild. + +Sun Mar 29 21:19:46 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_get_tracepoint_info): Change formatting of address. + (tracepoint_exists): Remove code which confuses assembly traces. + +Sat Mar 28 12:13:23 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_cmd): If argc > 2, assume that the busy and idle hooks + should not be called. + +Thu Mar 26 22:29:28 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * gdbtk.c: (gdb_trace_status) new function. + (gdbtk_init) added command "gdb_is_tracing". + (tracepoint_notify) added passcount information. + +Thu Mar 26 12:00:35 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_fputs): Insert fencepost. + (gdb_loc): Correct pc calculation. + (gdb_immediate_command): Return if a load is in progress. + (gdb_cmd): Return if a load is in progress. + (target_stop_wrapper): New function. + (gdb_stop): Call target_stop_wrapper. + (x_event): Add fencepost and optimize load cancel check. + (gdbtk_start_timer): Set up structs only once. + (gdbtk_stop_timer): Just use preset structs to set timer parameters. + (gdb_loadfile): If file cannot be loaded, return error message. + (gdb_loadfile): Add space before tab so that lines without + a '-' can later be changed to have one. + +Wed Mar 25 14:08:51 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * gdbtk.c (gdbtk_pre_add_symbol): Use Tcl_merge to form Tcl commands. + +Mon Mar 23 13:41:39 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * gdbtk.c (gdb_get_mem): Rewrite to fetch entire contents + of the memory window at once. + +Sat Mar 21 19:34:49 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + Merged changes from Foundry: list follows by author: + + - Tom Tromey <tromey@cygnus.com> + + * Makefile.in (gdbres.o): New target. + (WINDRES): New define. + * configure: Rebuilt. + * configure.in (WINDRES): Define. + (CONFIG_OBS): Include gdbres.o on Windows. + * gdbtool.ico: New file. + * gdb.rc: New file. + * gdbtk.c (gdbtk_init): Call ide_create_messagebox_command. + (gdbtk_cleanup): Call ide_interface_deregister_all. + (gdbtk_init): Pass event handle to cleanup. + (TclDebug): Use Tcl_Merge to construct command. + (gdbtk_init): Call ide_create_cygwin_path_command. + + - Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_set_bp): Set addr_string for bp. + (gdb_get_breakpoint_info): Demangle function + names in breakpoint info. + Include "demangle.h". + (gdb_loc, gdb_listfuncs): Demangle C++ + function names. + (gdb_set_bp): Properly quote filename to fix + problems with spaces. Send pc back as a hex string. + (gdb_listfuncs): Remove debugging line. + Turn off some debugging lines. + (breakpoint_notify): Return correct line number. + (gdb_get_breakpoint_info): Return correct line number. + (gdb_set_bp): New function to provide a better way to + set breakpoints. + (gdbtk_readline, gdbtk_readline_begin): Memory + allocated by tcl needs to be freed by Tcl_Free(). + (find_file_in_dir): Deleted. + (gdb_find_file_command): Call full_lookup_symtab(). + (gdb_listfuncs): Call full_lookup_symtab(). + (full_lookup_symtab): New function. Like lookup_symtab + except handles multiple files with the same basename, + full pathnames, and always sets symtab->fullname. + (gdb_loadfile): Call full_lookup_symtab(). Clear + realloc'd memory. + (gdb_loadfile): Don't tag lines without source. + Tag source lines with source_tag. + (gdb_find_file_command, find_file_in_dir): + Rewrite. Now searches symtabs and psymtabs for a match + on the partial or full filename. Returns the full pathname. + (gdb_loadfile): Realloc additional memory + if someone loads in a file with more than 160,000 + lines. I don't know if this really works because + I don't have enough memory to test it. + (gdb_sourcelines): Deleted. + (gdb_loadfile): New function. Takes a text widget + and loads it with the contents of a file. Marks + and tags source lines. + (pc_changed): New function. + (get_pc_register): Returns the value of + the PC to GDB. + (gdb_loc): If looking on the stack, return + real pc along with calling source line. + (gdb_loc): Return "" instead of "N/A" if + filename is not found. + (gdb_get_breakpoint_info): Same. + (get_register): For Natural mode, set format to 0. + Minor bugfixes from keiths. + (TclDebug): New function for debugging use. + (gdb_loc): Return correct PC for frames + that are not the innermost frame. + (gdb_listfiles): Rewritten to use object + API. Now takes an optional dirname which will cause + only files in that directory or its subdirectories + to be returned. Now returns basenames instead of + full pathnames. + (gdb_cmd): Set/reset load_in_progress flag. + (call_wrapper): Don't pop up dialog for errors in + downloads; just abort download. + (gdbtk_load_hash): Set return value correctly. + + - Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdbtk_init): Define the ui_loop_hook so that it can be + called by routines which might block, allowing us to update the GUI. + (gdbtk_wait): Move timer calls to annotation hooks. + (gdbtk_init): Define the annotation hooks. + (gdbtk_annotate_starting): New function for cygwin32 hosts. + (gdbtk_annotate_stopped): New function for cygwin32 hosts. + (gdbtk_annotate_exited): New function for cygwin32 hosts. + (gdbtk_annotate_signalled): New function. for cygwin32 hosts. + (gdbtk_init): Use gdbtk_print_frame_info hook. + (gdbtk_print_frame_info): New function which sets current_source_symtab + based on the given symtab and line info. + (gdb_immediate_command): New function which does + not buffer any + output. (Contrast to gdb_cmd.) + (gdb_prompt_command): New function to return gdb's prompt. + (find_file_in_dir): New functon which searches source paths + for a given filename. + (gdb_find_file): New function which returns path to given file -- uses + find_file_in_dir. + (gdbtk_init): Install "gdb_immediate", "gdb_find_file", and + "gdb_prompt" + commands into interpreter. + + - Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdbtk_timer_going): If __CYGWIN32__, new static + variable. + (gdb_cmd): If __CYGWIN32__, if executing the load command, call + gdbtk_start_timer and gdbtk_stop_timer. + (call_wrapper): If __CYGWIN32__, if the timer is going, turn it + off. Clear load_in_progress. + (x_event): If load_in_progress, quit if download_cancel_ok. + (gdbtk_start_timer): Set gdbtk_timer_going. + (gdbtk_stop_timer): Clear gdbtk_timer_going. + (gdbtk_wait): Call x_event. + (gdbtk_init): Call ide_create_win_grab_command if + __CYGIN32__. + (gdb_clear_file): Clear stop_pc. + +Wed Mar 4 16:50:18 1998 Jason Molenda (crash@bugshack.cygnus.com) + + * gdbtk.c (gdb_listfiles): Fix thinko in last change. + +Wed Mar 4 15:34:49 1998 Jason Molenda (crash@bugshack.cygnus.com) + + * gdbtk.c (gdb_listfiles): Allocate space for 'files' dynamically. + +Tue Feb 10 17:50:37 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdbtk_modify_tracepoint): Define new tracepoint modification hook. + (gdbtk_print_frame_info): Define this hook so that current_source_symtab + is set properly. + (gdb_actions_command): Use free_actions () from tracepoint.c/h. + +Mon Jan 26 11:37:55 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_actions_command): Make note of next action + before freeing all references to it. + +Sat Jan 24 23:52:08 1998 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c: Merge from Foundry branch. + (TclDebug): New debugging function. + (gdb_loc): For frames, find address of calling function + instead of whatever is on the stack (usually the next + instruction). + (gdb_listfiles): Takes an optional pathname argument and + returns an alphabetized list of basenames of files in the + path. + +Wed Jan 22 10:37:02 1998 Keith Seitz <keiths@onions.cygnus.com> + + * symfile.c: Define two new hooks for symbol reading: + "pre_add_symbol_hook" and "post_add_symbol_hook". These hooks + are called before we begin reading symbols, and after we finish. + (generic_load): Use new symbol reading hooks and get rid of + compiler warning. + + * gdbtk.c (gdbtk_init): Add hooks for pre- and post-symbol reading. + (gdbtk_pre_add_symbol): New function: the pre-add-symbol hook. + (gdbtk_post_add_symbol): New function: the post-add-symbol hook. + (find_file_in_dir): New function. Moved the guts of gdb_find_file_command + into here to allow its use by others. + (gdb_loc): Use find_file_in_dir to return the real path to the file + (or "N/A" if we can't find it). + + * configure.in (TIX_LIB_EXT): Define new variable for those special cases + when TCL_SHLIB_SUFFIX is not enough to specify the dependency. + + * configure: Regenerate. + +Fri Jan 23 07:47:06 1998 Fred Fish <fnf@cygnus.com> + + * Makefile.in (uninstall): Remove installed gdbtcl dir, if one + was installed. + +Thu Jan 15 12:42:28 1998 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_immediate_command): New function which does not buffer any + output. (Contrast to gdb_cmd.) + (gdbtk_init): Install "gdb_immediate" command into interpreter. + +Wed Jan 14 16:38:44 1998 Keith Seitz <keiths@pizza.cygnus.com> + + * configure.in (--enable-gdbtk): If tcl was built with --enable-shared, + use TCL_SHLIB_SUFFIX to specify the suffix of the library file so that + we don't expect to see "libfoo.a" instead of "libfoo.{so,sl, etc}". + + * configure: Regenerate. + +Wed Dec 31 16:50:26 1998 Keith Seitz (keiths@onions.cygnus.com) + + * gdbtk.c (gdb_actions_command): extract and save step count + from "while-stepping" command + +Tue Dec 16 21:16:42 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (LIBGUI): New variable. + (GUI_CFLAGS_X): New variable. + (IDE_CFLAGS): Add $(GUI_CFLAGS_X). + * configure.in: Add $(LIBGUI) to TCL_LIBS and CONFIG_DEPS. + * configure: Rebuild. + +Wed Dec 10 13:16:45 1997 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_get_tracepoint_info): Use info in struct + symtab_and_line (not struct tracepoint) so that we get the + real line info for an address. Arrange data more like + gdb_get_breakpoint_info. + (tracepoint_notify): Use info in struct symtab_and_line again. + (gdbtk_init): Add command "gdb_get_tracepoint_list" into + interpreter. + (gdb_get_tracepoint_list): New function that aids the source + window in displaying tracepoints when the file changes. + +Fri Dec 5 10:31:23 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * gdbtk.c (gdbtk_init): Add gdb_find_file into interpreter. + (gdb_find_file_command): New function which searches source path + to find the real full filename of a file. + +Mon Dec 1 10:19:44 1997 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c: Move include of "guitcl.h" back out of IDE ifdef. + (gdbtk_init): Move ide_initialize_paths out of IDE ifdef. + + * configure.in (TCL_LIBS, CONFIG_DEPS): Add IDE libraries for all + builds. + (CONFIG_OBS): Remove tracepoint.o, which should always be included. + + * configure: regenerate + + * Makefile.in (install-only): ALWAYS install the new gdbtk + (REMOTE_OBS): add tracepoint.o + +Thu Nov 27 09:07:18 1997 Michael Meissner <meissner@cygnus.com> + + * configure.in ({TCL_LIBS,CONFIG_DEPS}): Don't add IDE libraries + if not --enable-ide. + (CONFIG_OBS): Add tracepoint.o to list if --enable-gdbtk. + * configure: Regenerate. + + * gdbtk.c (gdb_get_breakpoint_info): Add missing filename + argument. + (toplevel): Move include of guitcl.h into #ifdef IDE region. + (gdbtk_init): Move ide_initialize_paths call into #ifdef IDE + section. + + * Makefile.in (gdbtk.o): Update dependencies. + +Wed Nov 26 15:02:43 1997 Keith Seitz <keiths@onions.cygnus.com> + + * gdbtk.c (gdb_loc): symtab_to_filename can return NULL. + (breakpoint_notify): Ditto. + (gdb_get_breakpoint_info): Ditto. + +Wed Nov 26 11:33:09 1997 Keith Seitz <keiths@onions.cygnus.com> + + Merge in code from Foundry branch: + + * Makefile.in (install-only): install the new gdbtk, not the old + + * gdbtk.c (gdbtk_call_command): also run idle hooks for class_trace + commands + (gdbtk_init): Add new commands "gdb_get_locals", "gdb_get_args", + "gdb_get_function", "gdb_get_line", "gdb_get_file", + "gdb_tracepoint_exists", "gdb_get_tracepoint_info", "gdb_actions", + and "gdb_prompt". + (gdb_get_vars_command): New function. + (gdb_get_line_command): New. + (gdb_get_file_command): New. + (gdb_get_function_command): New. + (gdb_get_tracepoint_info): New. + (gdbtk_create_tracepoint): New. + (gdbtk_delete_tracepoint): New. + (tracepoint_notify): New. + (tracepoint_exists): New. + (gdb_actions_command): New. + (gdb_tracepoint_exists_command): New. + (gdb_prompt_command): New. + +Thu Nov 13 18:15:54 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c: Move include of gdbcore.h to top of file. + (close_bfds): New static function if _WIN32. + (gdbtk_readline): Call close_bfds. + (call_wrapper, tk_command_loop): Likewise. + (gdb_clear_file): New static function. + (gdbtk_init): Create gdb_clear_file Tcl command. + +Wed Nov 12 14:58:39 1997 Jeff Holcomb <jeffh@cygnus.com> + + * gdbtk.c: gdbtk_load_hash and ui_load_progress_hook return an + int result. + (gdbtk_load_hash): download hash routine returns an int result. + +Mon Nov 10 15:11:51 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdbtk_init): Call ide_create_shell_execute_command if + __CYGWIN32__. + * configure.in: Add -lshell32 to WIN32LIBS on cygwin32. + * configure: Rebuild. + +Sun Nov 9 16:25:34 1997 Tom Tromey <tromey@cygnus.com> + + * gdbtk.c (gdbtk_init): Run ide_create_help_command. + +Tue Oct 28 17:31:47 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_init): Call ide_create_winprint_command. + +Thu Oct 23 15:53:37 1997 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Add -lgdi32 to WIN32LIBS when linking gdbtk on + cygwin32. + * configure: Rebuild. + +Wed Oct 22 21:32:54 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_init): Create sizebox command on Windows. + +Thu Oct 9 14:33:21 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdbtk_init): Remove assertion argument from call to + ide_create_window_register_command. + +Wed Oct 1 11:09:52 1997 Tom Tromey <tromey@cygnus.com> + + * gdbtk.c (gdbtk_init): Pass name of restore interface to + ide_create_window_register_command. + +Fri Sep 26 21:08:22 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * gdbtk.c (gdbtk_init): Initialize ui_load_progress_hook. + +Thu Sep 25 03:05:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_load_info): New function. Returns a list + of section names and sizes for an executable. + (gdbtk_load_hash): Stub function to call tcl function + download_hash. + +Tue Sep 23 01:29:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_get_mem): Fix compiler warning. + +Sun Sep 21 00:15:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_get_mem): Fix problem with ASCII dump. + +Tue Sep 16 18:07:17 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_get_mem): New function. Returns + a formatted memory dump with optional ASCII dump. + +Mon Sep 8 12:48:50 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c: Include ilutk.h if IDE. + (gdb_confirm_quit, gdb_force_quit): New static functions. + (gdbtk_init): Add Tcl commands gdb_confirm_quit and + gdb_force_quit. + +Mon Sep 8 03:05:33 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_get_breakpoint_info): Now returns the + function a breakpoint is in. + +Fri Sep 5 20:23:58 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdbtk_init): Call ide_create_exit_command. + +Wed Sep 3 19:39:15 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c: Include guitcl.h. + (gdbtk_init): Always call ide_initialize_paths. Set the Tcl + variable IDE to 1 when using the IDE. Always try using auto path + to find main.tcl. + * Makefile.in (IDE_CFLAGS_X): Always include libide. + (LIBIDE): New variable. + (IDE_X): Omit -lide. + (IDE_DEPS): Omit libide. + * configure.in: Add LIBIDE to TCL_LIBS and CONFIG_DEPS. + * configure: Rebuild. + +Mon Aug 25 02:28:55 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * gdbtk.c: (gdb_target_has_inferior) check if inferior_pid is non-zero + before assuming that the inferior is running. + +Mon Aug 25 01:06:48 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdbtk_start_timer): Pass third argument to setitimer. + (gdbtk_stop_timer): Likewise. + +Mon Aug 25 00:23:08 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * gdbtk.c: (gdbtk_init) create new command "gdb_target_has_execution" + (gdb_target_has_execution_command) new function + +Sun Aug 24 20:27:22 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdb_loc): If there are no symbols, just bail + immediately. + (tk_command_loop): Print errors encountered while running + gdbtk_tcl_preloop. + +Sun Aug 24 13:44:03 1997 Tom Tromey <tromey@cygnus.com> + + * gdbtk.c (gdbtk_init): Run ide_create_build_command. + +Sat Aug 23 21:53:39 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c: If CYGWIN32, include <sys/time.h>. + (x_fd): Don't define if WINNT. + (gdbtk_start_timer, gdbtk_stop_timer): New static functions if + CYGWIN32. + (gdbtk_wait): Don't set up signal handling if WINNT. If CYGWIN32, + call gdbtk_start_timer and gdbtk_stop_timer. + (gdbtk_init): Don't set up signal handling or make x_fd + asynchronous if CYGWIN32. + +Fri Aug 22 15:23:15 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (error_string_ptr): New static variable. + (gdbtk_fputs): If result_ptr is NULL, and error_string_ptr is not + NULL, and we're outputting to stderr, append string to + error_string_ptr rather than calling gdbtk_tcl_fputs. + (call_wrapper): Set up error_string_ptr. Put both error string + and normal string in Tcl result. + + * gdbtk.c (gdbtk_init): Don't call ide_run_server_init until after + gdb has initialized. + +Thu Aug 21 19:14:38 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c: If _WIN32, include winuser.h. + (gdbtk_init): If _WIN32, use MessageBox to display an error + evaluating main.tcl. + +Thu Aug 21 00:48:00 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * gdbtk.c (gdbtk_init): Add call to ide_run_server_init(). + (gdb_cmd): For the load command, don't buffer the I/O. + +Wed Aug 20 11:41:22 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdbtk_query): Chaneg free() call to Tcl_Free(). + +Tue Aug 19 17:09:19 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (TCL_DEPS, TK_DEPS): New variables. + (ITCL_DEPS, TIX_DEPS): New variables. + (IDE_DEPS): New variable. + (CDEPS): Include @CONFIG_DEPS@. + * configure.in: Set and substitute CONFIG_DEPS and TIX_DEPS. + * configure: Rebuild. + +Sun Aug 17 00:42:11 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (gdb_listfuncs): New function that returns + a list of all the functions in a source file. + +Tue Aug 12 16:35:21 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (install-only): Install tclIndex if ENABLE_IDE. + +Mon Aug 11 10:43:04 1997 Tom Tromey <tromey@cygnus.com> + + * gdbtk.c (gdbtk_init): Use ide_event_init_from_environment. + +Fri Aug 8 15:59:24 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdbtk_init): Change gdbtk_lib_tmp and gdbtk_file to be + dynamically allocated, rather than fixed size. Pass "gdbtcl" to + ide_initialize_paths to match installed directory name. If IDE, + use auto_path to search for main.tcl. + * Makefile.in (install-only): If ENABLE_IDE, install from gdbtcl2 + rather than gdbtcl. + + * gdbtk.c (gdbtk_cleanup): New static function. + (gdbtk_init): Add gdbtk_cleanup as a final cleanup. Uncomment + call to ide_initialize_paths. If we can't initialize the event + system, set GDBTK_IDE to 0 in the Tcl interpreter. Create the + ide_window_register and the ide_window commands. Initialize tk, + itcl, and tix after initializing the IDE. + + * configure.in (tixdir): Update for cygwin32 case for Tcl 8.0. + * configure: Rebuild. + +Fri Aug 8 00:13:32 1997 Martin M. Hunt <hunt@cygnus.com> + + * gdbtk.c (breakpoint_notify): Change buffer size from 100 + to 256 to avoid memory corruption with very long pathnames. + +Thu Aug 7 14:08:23 1997 Martin M. Hunt <hunt@cygnus.com> + + * configure.in: Change required Tix version to 4.1.8.0 . + * configure: Rebuilt. + +Fri Aug 1 15:21:44 1997 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (Tcl_Alloc): Don't provide our own version of this if + _WIN32. + (Tcl_Realloc, Tcl_Free): Likewise. + * configure.in: Check for cygwin32 environment. Define and + substitute WIN32LIBS and WIN32LDAPP. Always set configdir to + unix; setting it to win was for an old Tcl/Tk configuration + scheme. + * aclocal.m4 (CY_AC_LOAD_TKCONFIG): Substitute TK_BUILD_INCLUDES. + * Makefile.in (TK_CFLAGS): Add @TK_BUILD_INCLUDES@. + (WIN32LDAPP, WIN32LIBS): Define. + (CLIBS): Add $(WIN32LIBS). + (gdb): Use $(WIN32LDAPP). + * configure: Rebuild. + +Tue Jul 22 19:45:37 1997 Martin M. Hunt <hunt@cygnus.com> + + * configure.in, aclocal.m4: Another fix to find the + correct Tix library name. + + * configure: Rebuilt. + +Mon Jul 21 22:24:07 1997 Martin M. Hunt <hunt@cygnus.com> + + * aclocal.m4: Search for the correct tix library. + +Thu Jul 10 00:02:41 1997 Martin M. Hunt <hunt@cygnus.com> + + * Makefile.in, configure.in, aclocal.m4: Add Itcl, Tix, and + IDE configuration information. + + * gdbtk.c (breakpoint_notify): Send address, linenumber and + filename when a breakpoint is set. Avoids call to bp_info. + (gdbtk_init): Call Tcl_FindExecutable(). Add code to handle + Itcl, Tix and IDE initialization. + + * configure: Regenerated. + +Fri Jun 13 10:28:09 1997 Fred Fish <fnf@cygnus.com> + + * gdbtk.c (gdbtk_init): Make truth value test explicit. + Remove unused static variable "Gdbtk_Library". + +Sat Jun 7 02:34:19 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + * gdbtk.c (gdb_get_breakpoint_info): Add string for new + enumeration del_at_next_stop to bpdisp array. + +Tue Jun 3 15:46:51 1997 Tom Tromey <tromey@cygnus.com> + + * Makefile.in (LIB_RUNTIME_DIR): New variable. + +Wed May 7 19:10:19 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * gdbtk.c (wrapped_call): New function - make actual call to tk + worker function. + (call_wrapper): Rewrite to use top.c:catch_errors. + + * gdbtk.c (gdb_stop): If No target_stop set quit flag and hope for + best. + +Mon Apr 21 14:00:08 1997 Doug Evans <dje@canuck.cygnus.com> + + * gdbtk.c (gdb_disassemble): Store endian-ness in `di'. + +Wed Apr 16 12:33:06 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * Makefile.in (install-only): Make list of gdbtcl files to install + explicit - was picking up files such as ChangeLog etc. + (install-only): Don't blindly create the directory. + +Tue Apr 1 15:04:21 1997 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * configure.in (gdbtcl): Create soft-link for gdbtcl/ directory + instead of gdbtk.tcl. + +Fri Mar 28 17:04:02 1997 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (gdbtk.o): look for GDBTK_LIBRARY in $(datadir) by + default, not $(srcdir). + +Wed Mar 19 15:16:17 1997 Martin M. Hunt <hunt@onions.cygnus.com> + + * Makefile.in: Install gdbtcl dir instead of gdbtk.tcl. + + * gdbtk.c: Added some ifdefs for Windows. Changed GDBTK_FILENAME + to GDBTK_LIBRARY, which is now a path to search. + (gdb_path_conv): New function. Convert Cygwin32 pathname to + DOS-style pathname. + + * {aclocal.m4,configure.in}: Changes for Windows builds. + + * configure: Rebuilt. + +Fri Mar 14 10:01:29 1997 Tom Tromey <tromey@cygnus.com> + + * configure: Regenerated. + * configure.in (LIBS): Re-reverse order of TCL_LIBS and TK_LIBS. + +Wed Mar 12 14:29:52 1997 Tom Tromey <tromey@cygnus.com> + + * gdbtk.c (x_event): Use Tcl_DoOneEvent, TCL_DONT_WAIT, + TCL_ALL_EVENTS. + + * configure: Regenerated. + * configure.in (ENABLE_GDBTK): Put TCL_LIBS after TK_LIBS in + LIBS. + +Mon Feb 10 13:50:53 1997 Stu Grossman (grossman@critters.cygnus.com) + + * gdbtk.c (call_wrapper): Clear running_now if an error occurs. + +Wed Dec 11 18:51:35 1996 Mark Alexander <marka@cygnus.com> + + * gdbtk.c (gdb_loc): Correct truncation of PC on 64-bit MIPS. + +Tue Nov 19 09:26:14 1996 Tom Tromey <tromey@cygnus.com> + + * gdbtk.c (gdbtk_readline): Fix memory leak. + +Mon Nov 18 23:43:05 1996 Tom Tromey <tromey@cygnus.com> + + Fixes for Tcl 7.6 / Tk 4.2: + * gdbtk.tcl (apply_filespec): Use tk_getOpenFile. + Remove old fileselect code. + * gdbtk.c (Tcl_Alloc): Rename from Tcl_Malloc. + +Fri Sep 27 10:25:30 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (create_copyright_window): Increase timeout from + 15 seconds to 30 seconds. + +Wed Sep 4 17:28:40 1996 Stu Grossman (grossman@critters.cygnus.com) + + * configure configure.in: Add host *windows* to list of hosts + that don't support GDBtk. + +Fri Aug 23 00:44:57 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.c (gdbtk_init): Check for a DISPLAY env variable and + gracefully degrade to using command line interface if none is + found. + +Fri Aug 9 12:32:53 1996 Tom Tromey <tromey@creche.cygnus.com> + + * Makefile.in (LIB_INSTALL_DIR): New macro. + (TCL): Include @TCL_LD_SEARCH_FLAGS@. + +Thu Aug 1 20:35:01 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.c (mainWindow): Deleted. + (cleanup_init): Don't destroy main window. + (gdbtk_init): Main window now created by Tk_Init. + + * configure.in: Most X checks now handled automatically by Tk. + Use new macros to find Tcl/Tk. + * aclocal.m4: New version for new Tcl/Tk; from Don Libes. + * config.in, configure: Regenerated. + + * Makefile.in (TCL, TCL_CFLAGS, TK, TK_CFLAGS, X11_CFLAGS, + X11_LDFLAGS, X11_LIBS): Changed for new Tcl and Tk. + +Thu Aug 1 16:12:05 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (gdbtk.tcl): put in $(datadir), not $(libdir). + +Fri Jul 26 14:07:37 1996 Ian Lance Taylor <ian@cygnus.com> + + * gdbtk.c (gdb_disassemble): Initialize di.flavour. + +Thu Jul 25 19:41:31 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.c (null_routine): Ditto. + (gdbtk_flush): Ditto. + (gdbtk_fputs): Ditto. + (gdbtk_query): Ditto. + (gdbtk_readline): Ditto. + (gdbtk_readline_end): Ditto. + (gdb_get_breakpoint_list): Ditto. + (gdb_get_breakpoint_info): Ditto. + (breakpoint_notify): Ditto. + (gdbtk_create_breakpoint): Ditto. + (gdbtk_delete_breakpoint): Ditto. + (gdbtk_modify_breakpoint): Ditto. + (gdb_loc): Ditto. + (gdb_eval): Ditto. + (gdb_sourcelines): Ditto. + (map_arg_registers): Ditto. + (get_register_name): Ditto. + (gdb_regnames): Ditto. + (get_register): Ditto. + (gdb_fetch_registers): Ditto. + (register_changed_p): Ditto. + (gdb_changed_register_list): Ditto. + (gdb_cmd): Ditto. + (call_wrapper): Ditto. + (gdb_listfiles): Ditto. + (gdb_stop): Ditto. + (gdbtk_dis_asm_read_memory): Ditto. + (compare_lines): Ditto. + (gdb_disassemble): Ditto. + (tk_command): Ditto. + (cleanup_init): Ditto. + (gdbtk_interactive): Ditto. + (x_event): Ditto. + (gdbtk_wait): Ditto. + (gdbtk_call_command): Ditto. + (tk_command_loop): Ditto. + (gdbtk_init): Ditto. + + * gdbtk.c (register_changed_p): Remove unused local variable "buf". + +Sat Jul 20 17:46:40 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (files_command): Reorder the binding tags for + the listbox widget to avoid referencing the listbox after + the containing widget has been destroyed by the action of + a previous binding. + +Sat Jul 20 10:09:28 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (delete_expr): Unset corresponding element of + expr_update_list when destroying an expression. + (create_expr_window): Initialize expr_num, delete_expr_num, + and expr_update_list here when each new expression window + is created, rather than once at startup. + +Mon Jul 15 16:44:05 1996 Stu Grossman (grossman@critters.cygnus.com) + + * gdbtk.c (gdb_disassemble): Setup di.mach from + tm_print_insn_info.mach, and set endian from TARGET_BYTE_ORDER. + +Fri Jun 21 11:04:47 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (create_register_windows): Include missing '$'s. + Add global declarations for various reg_format_* variables. + * gdbtk.tcl (populate_register_window): Make initial window one + line taller to account for new column header line. + +Fri Jun 21 09:46:47 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.c (get_register): Support for printing raw formats. + * gdbtk.tcl: Add hint for using debug_interface. + (center_window, add_breakpoint_frame, delete_breakpoint_frame): + Enclose arg in braces for consistency. + (create_registers_window, populate_reg_window, update_registers): + Major rewrite to support displaying multiple formats in the register + window. + (init_reg_info): New function. + (recompute_reg_display_list): Reset reg_display_list, start + register display lines at line 2. + +Thu Jun 20 08:18:59 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (gdbtk_tcl_readline_begin): Handle backspace to + avoid backing up over prompt. At every input, make sure insert + point is at least after command start, handle control-u to delete + current input line. + (tclsh): Handle backspace to avoid backing up over prompt. Handle + control-u to delete current input line. + +Wed Jun 19 17:23:38 1996 Geoffrey Noer <noer@cygnus.com> + + * configure.in: disable gdbtk for *cygwin32* hosted compiles + * configure: regenerated with autoconf 2.8 + +Sun May 19 16:49:37 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.c (gdbtk_readline_begin, gdbtk_readline, gdbtk_readline_end): + New functions. + (tk_command_loop): Set instream to NULL to enable Tk user interaction. + (gdbtk_init): Set readline_begin_hook, readline_hook, + and readline_end_hook. + * gdbtk.tcl (gdbtk_tcl_readline_begin, gdbtk_tcl_readline, + gdbtk_tcl_readline_end): New functions. + (tclsh): Pack scroll bar on right side of window, not left. + +Fri May 17 13:54:34 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (create_command_window): Change a misspelled "get" + to the intended "cget". + (delete_line): Fix so it deletes the current line at the + insertion cursor. + +Thu May 16 19:20:29 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (gdb_prompt): Set this early on. + (create_command_window): Use gdb_prompt rather than "(gdb) ". + (gdbtk_tcl_preloop): Proc executed just prior to Tk main loop. + (tclsh): If an evaluation window already exists, just bring it + to the front instead of trying to create another. + * gdbtk.c (tk_command_loop): New function. + (gdbtk_init): Call tk_command_loop rather than Tk_MainLoop. + +Thu May 16 16:16:35 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.tcl (evaluate_tcl_command, tclsh): New functions that + implement a tcl evaluation window for gdbtk maintainers to use. + +Thu May 16 11:42:58 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.tcl (files_command): Correctly insert list of files into + listbox widget. + + * gdbtk.tcl (files_command): listbox command no longer accepts + -geometry. + +Wed May 15 16:04:09 1996 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.tcl (create_command_window): If command window's buffer + is disabled, don't execute any of the key bindings. + +Mon May 13 13:43:25 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.c (tk_command): Catch case where no argument is given + since this will cause the tcl interpreter to dump core. + +Wed May 8 20:33:24 1996 Fred Fish <fnf@cygnus.com> + + * gdbtk.c: Fix a couple of misspellings. + +Thu May 2 19:17:49 1996 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.tcl (debug_interface): New global, use to aid debugging. + (insert_breakpoint_tag, delete_breakpoint_tag): Fix range. + (file_popup_menu): Delete, never used. + (listing_window_popup): Rename from listing_window_button_1, + remove breakpoint toggling code. + (toggle_breakpoint): New procedure. + (create_file_win): Bind popup menu to button 2, toggle breakpoints + with button 1 in breakpoint area, add display of tagged areas if + debugging on. + +Fri Apr 5 13:44:40 1996 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.c (running_now): New global variable. + (gdb_cmd): Test it before executing any command. + (gdbtk_call_command): Set it when inferior is running. + * gdbtk.tcl (gdbtk_tcl_busy, gdbtk_tcl_idle): Enable and + disable interaction with command window's text appropriately. + +Fri Apr 5 13:25:42 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * gdbtk.c (SIOCSPGRP, linux): If on Linux, undef SIOCSPGRP, since + some versions of the kernel don't support it. + +Tue Feb 6 16:31:25 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.tcl (create_file_win): Eliminate text widget B1 binding so + double-clicking will work again. + (create_asm_win): Put "break" at end of all B1 bindings. + (create_file_win): Lower "sel" tag, don't raise it. + (ensure_line_visible): New proc. + (update_listing, update_assembly): Use it. + (create_copyright_window): Destroy window on Leave event. + (create_command_window): Put "break" at end of all B2 bindings. + +Wed Jan 24 15:28:41 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.tcl, gdbtk.c: Updated copyrights. + + * configure.in: Look for -ldl or -ldld when using Tcl 7.5 or + greater. + * configure: Rebuilt. + +Tue Jan 23 09:00:48 1996 Doug Evans <dje@charmed.cygnus.com> + + * gdbtk.c (gdb_disassemble): Pass fprintf_unfiltered to + INIT_DISASSEMBLE_INFO. + +Mon Jan 15 09:58:41 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.tcl (create_expr_window): Many changes to update GUI. + (add_expr): Changes from create_expr_window. + (create_command_window): Set focus. + (delete_expr): Rewrote. + (expr_update_button): New proc. + (add_expr): Put bindings on FocusIn, FocusOut. + Don't allow .file_popup to be torn off. + +Fri Jan 12 09:36:17 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.tcl (gdbtk_tcl_query): Swap Yes and No buttons. + (update_listing): Use lassign. Use "see" to scroll. Don't need + screen_top, screen_bot, screen_height. + (update_assembly): Use "see" to scroll. + (textscrollproc): Removed. + (create_file_win): Don't use textscrollproc. + (asmscrollproc): Removed. + (create_asm_window): Don't use asmscrollproc. + (create_asm_win): Ditto. + (screen_height, screen_top, screen_bot): Removed. + (run_editor): New proc. + (build_framework): Use it. + (create_file_win, create_source_window): Don't use textscrollproc. + (create_breakpoints_window): Set -xscrollcommand on canvas. + (not_implemented_yet): Default button is 0. + (delete_char): Don't use tk_textBackspace. + (create_command_window): Allow Tk bindings to fire after deleting + character. + (create_command_window): Make Delete delete left, not right. + +Thu Jan 11 10:08:14 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.tcl (FSBox): Don't use tk_listboxSingleSelect. + + Changes in sync with expect: + * configure.in (ENABLE_GDBTK): Use CY_AC_PATH_TCL and + CY_AC_PATH_TK. + * aclocal.m4: Replaced with version from expect. + * configure: Regenerated. + +Wed Jan 10 09:07:22 1996 Tom Tromey <tromey@creche.cygnus.com> + + * gdbtk.tcl (gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, + gdbtk_tcl_flush): Use "see", not "yview". + (gdbtk_tcl_query): Use questhead bitmap. + various: Always wrap condition of 'if' in {...}. + (add_breakpoint_frame): Set -value on radiobuttons. + (lassign): New proc. + (add_breakpoint_frame): Use lassign, not series of assignments. + (decr): Made faster. + (interactive_cmd): Use "see", not "yview". + (not_implemented_yet): Use warning bitmap. + (update_expr): Don't allow $expr to be evalled by Tcl. + (create_expr_window): Don't use "focus". + (delete_char, delete_line): Define globally. + (delete_line, delete_char, create_command_window, update_autocmd, + build_framework, create_asm_win, create_file_win): Use "see", not + "yview". + (create_copyright_window, center_window, bind_widget_after_class): + New procs. + (FSBox,create_command_window, create_autocmd_window): Binding + changes for Tk4. + (textscrollproc): Define globally. + (build_framework): tk_menuBar no longer needed. Keys Prior, Next, + Home, End, Up, and Down are all defined by Tk. + (apply_filespec): Use error bitmap in dialog. + (files_command): Don't use tk_listboxSingleSelect. + (files_command): Don't use "uniq" to remove duplicates from a + list. + (update_assembly): Use lassign. + (create_asm_win): Removed redundant bindings. + (listing_window_button_1, file_popup_menu): Use tk_popup. + (ButtonRelease-1 binding): Just remove tag from window; rest + handled by Tk. + + * gdbtk.c (gdbtk_query): Use Tcl_Merge to provide quoting. + (call_wrapper): Use Tcl_Eval, not Tcl_VarEval. + (gdbtk_call_command): Ditto. + +Thu Jan 4 16:04:54 1996 Stu Grossman (grossman@cygnus.com) + + * configure configure.in: Make --enable-gdbtk be the default. + +Thu Dec 28 15:10:49 1995 Stan Shebs <shebs@andros.cygnus.com> + + * README.GDBTK: Polish introductory paragraph. + +Mon Oct 16 11:27:06 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdb_disassemble): Use fprintf_unfiltered instead of + fprintf_filtered. + +Tue Oct 10 15:26:39 1995 Fred Fish <fnf@cygnus.com> + + * README.GDBTK: Updated for version 4.15. + +Sat Aug 19 17:20:22 1995 Michael Tiemann <tiemann@axon.cygnus.com> + + * gdbtk.tcl: ENABLE comes back as "1" or "0", not "enable" or + "disable". + Also, wire up the breakpoint window so that it can be demo'd. + +Tue Aug 1 11:44:53 1995 J.T. Conklin <jtc@rtl.cygnus.com> + + * gdbtk.c: Include "gdb_string.h" instead of <string.h>. + +Tue Jun 20 10:19:40 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c: Add functions Tcl_Malloc, Tcl_Realloc, and Tcl_Free. + + * gdbtk.tcl (add_breakpoint_frame): Add more fields. + * (create_file_win create_asm_win build_framework): Create null + bindings for meta keys to keep window from dropping down to + insertion point when meta is pressed by itself. New bindings: + Up/Down - Scroll up/down one line at a time + Next/Prior - Scroll up/down one page at a time + Home/End - Warp to current pc/end of file + * (build_framework): Turn on breakpoint menu. + * (create_command_window): Implement tab completion. Add binding + for ^C to stop target. + +Fri May 19 06:15:40 1995 Jim Kingdon <kingdon@deneb.cygnus.com> + + * gdbtk.c: Conditionalize use of stdarg rather than varargs on + ANSI_PROTOTYPES not __STDC__; it must match the definition of + PARAMS. + +Thu May 18 15:58:46 1995 J.T. Conklin <jtc@rtl.cygnus.com> + + * gdbtk.c (gdbtk_query): Use stdarg.h macros when compiling with + an ANSI compiler. + +Sat Apr 15 13:52:24 1995 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.c (gdb_disassemble): Read from inferior if connected + to a VxWorks target. + +Fri Apr 14 10:18:20 1995 Stu Grossman (grossman@cygnus.com) + + * README.GDBTK: New file. Contains the obvious. + +Tue Apr 11 11:07:12 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * gdbtk.c (gdbtk_init): If SIOCSPGRP is not available, but + F_SETOWN is, use that. + +Thu Apr 6 17:00:46 1995 Michael Meissner <meissner@tiktok.cygnus.com> + + * Makefile.in (X11_INCLUDES): Define as empty. + (X11_CFLAGS): Define as including $(X11_INCLUDES). + (X11_LIB_SWITCHES): Define as empty. + (X11_LIBS): Define as -lX11. + + * configure.in (enable_gdbtk): If gdbtk, support the --x-includes + and --x-libraries switches, setting the X11_INCLUDES and + X11_LIB_SWITCHES respectively. Instead of using a hardcoded -lX11 + in ENABLE_CLIBS, use the X11_LIB_SWITCHES and X11_LIBS variables. + + * gdbtk.c (gdbtk_init): If SIOCSPGRP is not available, don't use + it. This means that the stop button doesn't work, but is better + than nothing. + +Wed Mar 29 17:09:29 1995 Stu Grossman (grossman@cygnus.com) + + * Makefile.in (gdbtk.o): Use X11_CFLAGS to provide alternate + locations (per-host) for X11 include files. + * config/pa/hppahpux.mh (XM_CLIBS): Add -L/usr/lib/X11R5 to force + the use of R5 libs. + (X11_CFLAGS): Add this to indicate the locs + of the R5 include files. + +Wed Mar 8 16:12:21 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdb_get_breakpoint_info): Return error if breakpoint + type is not bp_breakpoint. + +Tue Feb 14 17:16:41 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c: Ditto. + * gdbtk.c: General cleanups, get rid of unused variables. Redo + handling of stdout/stderr to just return output as the result of + the tcl command that caused the output. Cleanup -Wall stuff. + * (breakpoint_notify): Now returns just action and breakpoint + number. + * (gdb_get_breakpoint_list): New routine. Does the obvious. + * (gdb_get_breakpoint_info): Mostly derived from the old + breakpoint_notify, but returns lots more info. + * (dsprintf_append_element): Helper routine, works like printf, + but appends a tcl element onto the specified DString. Good for + building up lists as return values. + * (gdbtk_enable/disable_breakpoint): Go away. Replaced with + gdbtk_modify_breakpoint. + * (*many routines*): Use new result protocol. + * (call_wrapper): Make sure that recursive calls don't trash results. + * gdbtk.tcl: New windows, autocmd, and breakpoints. + * (gdbtk_tcl_fputs): Don't use $current_output_win redirection + anymore. It's not needed (in fact, this routine may not be needed + anymore). + * (gdbtk_tcl_breakpoint): Change to reflect new breakpoint + notification protocol. + * (gdbtk_tcl_busy gdbtk_tcl_idle): Straighten out buttons, remove + catches. + * (interactive_cmd): Use this wrapper around button invocations + of many commands. This will catch errors and put the results into + the command window. It also updates all the other windows. + * Also, change reliefs of most things to sunken. This actually + looks better. + * (create_file_win): Fix margin binding to allow breakpoints to + work again. + * (create_asm_win): Use return value of gdb_disassemble instead + of implicit I/O to the command window. + * (create_command_window): Use new result protocol to get output + from commands. + +Sun Feb 5 20:32:44 1995 Jim Kingdon (kingdon@lioth.cygnus.com) + + * gdbtk.c (gdb_disassemble): Deference pointer to function before + calling it (pre-ANSI compilers generally require this). + +Fri Feb 3 11:19:20 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdb_disassemble): Get rid of + dis_asm_read_memory_hook. We can now call the disassemblers + directly and have no need for this hook anymore. + +Mon Jan 30 17:34:24 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl (create_file_win): Disable old popup menu for source + window. + +Wed Jan 25 18:23:46 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdbtk_init): Prevent segfault when gdbtk.tcl can't be + found. + * gdbtk.tcl: Initialize expr_update_list() to prevent errors when + popping up expression window for the first time. + +Tue Jan 24 12:10:28 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl (create_registers_window): Work around a radiobutton + widget bug to make Options|Natural button work. + + * gdbtk.c (gdb_disassemble): Fix problem with source+assembly and + g++ caused by out-of-order pc's. + * gdbtk.tcl (files_command): Remove duplicate file names. Also, + add scrollbar. + +Mon Jan 23 17:21:09 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl: Take .gdbtkinit if it exists. Makes gdbtk match the + doc! + +Thu Jan 12 15:02:40 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c, gdbtk.tcl: Update/add copyright. + * gdbtk.tcl (build_framework): Several fixes for filespec widget, + including dismiss button, and better error handling. + * (create_command_win): Bind button 2 to retrieve selection. + +Wed Jan 11 17:06:55 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl: Add button to control mixed source disassembly. + Use text widgets in expr window. The give me more control over + layout. + Add auto-updating of exprs in expression window. + Handle expressions out of scope a bit better. + Make selected window pop up to the top when invoked via the + menubar. + Make copyright message have raised relief. + + * gdbtk.c (gdbtk_init): Improve handling for errors in gdbtk.tcl + during startup. + +Thu Jan 5 17:38:29 1995 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (finish_saving_output): Don't do anything if not saving + output. + * (breakpoint_notify): Don't send null filename to tcl. + * (gdb_eval): New tcl command to eval an expression. + * (gdb_disassemble): New tcl command to do disassembly. This + allows tcl code to choose between exec file and target memeory, + and can also do mixed source and assembly. + * (gdbtk_init): Move reading of gdbtk.tcl to the end to make sure + that more of the environment is set up. Also, create link between + gdb and tcl vars disassemble{-_}from{-_}exec. + + * gdbtk.tcl: New expression window support. + * Make assembly window be 80 columns wide. + * Use new disassembly method. Add menu items to select + disassembly from exec file or target. + * Change View menubar item to Options. + + * Get rid of Stack, Breakpoints, Signals, and Variables Windows, + since they don't exist yet. + + * Pop up a copyright window on startup. + +Wed Jan 4 19:49:10 1995 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.tcl (build_framework): Add standard commands menu, more + windows to standard windows menu. + (not_implemented_yet): Clarify message. + +Fri Dec 30 15:49:00 1994 Stan Shebs <shebs@andros.cygnus.com> + + * gdbtk.tcl (FSBox): New proc, File Selection Box code from exmh. + (not_implemented_yet): New proc. + (build_framework): Add various file commands to file menu. + +Fri Dec 23 16:18:50 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdbtk_wait gdbtk_init): Portability improvements for + SIGIO handling. + +Mon Dec 19 09:55:47 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl (update_assembly): Force update to make sure that pc + is visible when creating new assembly windows. + +Sun Dec 18 23:31:20 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdbtk_wait gdbtk_init): Use different method of + enabling I/O interrupts for SVR4 (streams). + * (start_saving_output save_output get_saved_output + finish_saving_output flush_holdbuf gdbtk_flush gdbtk_fputs + gdbtk_init): + Totally revamp to use TCLs dynamic string functions. Also, quote + all data passed back to TCL to prevent errors with unmatched + braces, odd characters, etc... This fixes several wierd problems + with outputting strings containing unmatched braces. + * (breakpoint_notify gdb_loc): Use long hex format to output + addresses of breakpoints and PCs. This fixes some Alpha problems. + * (breakpoint_notify): Add stream arg to call to gdbtk_fputs. + * (gdb_listfiles): Also, go through the symtabs when looking for + files. This makes xcoff work (sort of), but probably breaks + something else. + * (gdb_stop): Return TCL_OK instead of nothing. This fixes odd + TCL errors when hitting stop button. + * (tk_command): Don't pass interp->result on to Tcl_{Var}Eval, as + that will trash the result. strdup the result instead and pass + that on. Improve error handling as well. + + * gdbtk.tcl (gdbtk_tcl_flush): Use global def of + current_output_win. Makes flushing actually work! + * (asm_win_name create_asm_win update_assembly): Bunch of fixes + to make assembly windows stop flashing when loading a new file. + * (gdbtk_tcl_busy gdbtk_tcl_idle): Use catch to prevent gdb_cmd + errors from losing control. + * (create_source_window): Add source file selection to View menu. + * (create_command_window (<Key-Return> binding): Quote text fed + into gdb_cmd to prevent eval errors. + +Thu Dec 15 16:40:10 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c: Improve mechanism for capturing output values. + (full_filename): Remove. + (gdb_cmd call_wrapper gdbtk_init): Protect all calls from tcl land + with call_wrapper. This prevents longjmps (usually via error()) + from jumping out of tcl/tk and leaving things in an indeterminate + state. + (gdbtk_fputs): Differentiate stdout from stderr when passing text + into tcl land. + * gdbtk.tcl: New view option to disable line numbers. Put catch + around most uses of gdb_cmd. Add update button to reg config + window. Stop doing immediate updates when selecting registers. + Change register view values into checkbuttons. + +Mon Dec 12 16:59:29 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl (reg_config_menu create_registers_window + recompute_reg_display_list): Use array instead of individual vars + for register display list. + * (recompute_reg_display_list update_registers): Fix bug with not + displaying all registers. + +Mon Dec 12 12:22:21 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c: New tcl commands: gdb_fetch_registers, + gdb_changed_register_list, and gdb_regnames. + * gdbtk.tcl: Use monochrome color model for now. + * (delete_breakpoint_tag create_file_win): Add breakdot support. + * (create_file_win create_asm_win update_listing build_framework + create_source_window create_command_window): Re-org window + creation to give all windows consistent look and feel. + * (update_listing update_asm): Change pc pointer to '->'. + * (registers_command reg_config_menu create_registers_window + populate_reg_window update_registers): Revamp register window. + Allow selection of registers to be displayed. Highlight changed + registers. + +Mon Nov 28 09:17:20 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl (build_framework): Fix bug with setting window titles. + + * gdbtk.tcl (build_framework): Add "Report bug" to help menu. + + * gdbtk.tcl: Re-arrange windows using new, consistent layout. Clean + up lots of code and centralize framework initialization. + +Wed Nov 16 15:28:29 1994 Rob Savoye (rob@cygnus.com) + + * Makefile.in: Fix the test for installing gdbtk. + +Mon Nov 14 08:51:29 1994 Stu Grossman (grossman@cygnus.com) + + * Makefile.in: Install gdbtk.tcl. + * configure.in: Add ENABLE_GDBTK flag. + * gdbtk.c (gdb_sourcelines): Returns list of source lines + containing code. (gdb_regnames): Returns list of register names. + +Thu Nov 3 14:25:24 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdb_stop): Switch to target_stop(). + +Tue Nov 1 16:41:12 1994 Stu Grossman (grossman@cygnus.com) + + * Makefile.in: Use $(objdir)/tcl and $(objdir)/tk if they are + available. + * configure.in (ENABLE_CLIBS): Use $(TCL) and $(TK) instead of + -ltcl and -ltk. + * gdbtk.c: Get rid of lots of unnecessary #includes. + * (gdbtk_init): Use ConnectionNumber macro instead of referencing + Display structure directly. + * gdbtk.tcl: Change exit button to quit button. + +Wed Oct 26 15:41:07 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c: Change sense and name of no_windows variable. Now + called use_windows, and defaults to off (for compatibility). + +Thu Oct 20 17:35:45 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdb_cmd): Force GUI into idle mode when errors occur. + * (gdb_stop): New tcl command to stop the target process. + * (x_event, gdbtk_wait): Allow GUI to interrupt gdb out of target + waits. + * (gdbtk_call_command): Wrapper around command processing to + alert GUI of target state changes. + * (gdbtk_init): Get the fd of X server for doing async + notification of X events (via x_event). Setup new hooks. + * gdbtk.tcl: Add scrollbars to assembly and command windows. + * Change window foreground & background colors. + * Create margin tag for breakpoints in source and assembly windows. + * Add new routines to be invoked when target state changes to/from + idle. + * Add start of expression window. + * Change bindings of mouse button 1 in assembly and source window + to just set or clear breakpoints when in the margin tag. + * Change shape of register window to be more vertical to better + reflect its contents. + * Add stop button. + * Cleanup some code around command window bindings. + +Sat Sep 17 17:05:14 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl: Let ^U delete lines in the command window. + +Fri Sep 16 15:40:34 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c: Replace calls to full_filename with symtab_to_filename. + * gdbtk.tcl: New routine pc_to_line replaces in line code. New + routine decr replaces in line code. + * (create_file_win): Use catch to handle open failures more + elegantly. Also, create special window to display file open + failure message. Move opening of file prior to creation of text + widget. + * (create_asm_win): Add PC as argument. We now base disassembly + on PC instead of function name, since function names can be + ambiguous (usually seen with shared libs). Also, use catch to + simplify code where we don't care about failures. + +Wed Sep 14 00:55:26 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.tcl: Add ref counts to breakpoint tags. + * Put quotes around function name in disassemble command to better + handle assembler names containing `.'. + * Make pclist element 0 be filler to avoid off-by-one problem with + line numbers. + * Set names of top-level windows. + * Add register display window. + * Add PC to label of assembly window. + +Tue Sep 13 08:59:04 1994 Stu Grossman (grossman@cygnus.com) + + * gdbtk.c (gdbtk_flush gdbtk_fputs): Buffer up output to make + disassembly more efficient. + * (breakpoint_notify): Include pc in gdbtk_tcl_breakpoint + callback. + * (gdb_loc): Include pc in return value. Also, return function + name if arg was specified. + * (gdb_cmd_stub): Call gdb_flush to drain internal GDB buffers + after command completes. + * (gdbtk_init): Improve error handling. + + * gdbtk.tcl: Add lots of comments. Clean up code. + * (gdbtk_tcl_fputs): Make output window redirectable. + * Add assembly window, and breapoint support. + * Make button 1 in margin toggle breakpoints. + * Use stippling to indicate breakpoint disabling. + +Fri Sep 2 19:11:40 1994 Stu Grossman (grossman@cygnus.com) + + * configure.in: Don't symlink to gdbtk.tcl if it's already there. + +Thu Jul 28 14:37:36 1994 Stu Grossman (grossman@cygnus.com) + + Support for TK GUI. + * Makefile.in: Add rule for gdbtk.o. + * configure.in: Add support for --enable-gdbtk. + * gdbtk.c: New file. Contains support routines for TK interface. + * gdbtk.tcl: New file. Implements GUI policy. + + +Local Variables: +mode: change-log +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/gdb/gdbtk/generic/gdbtk-cmds.c b/gdb/gdbtk/generic/gdbtk-cmds.c new file mode 100644 index 00000000000..656374bb386 --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk-cmds.c @@ -0,0 +1,4646 @@ +/* Tcl/Tk command definitions for gdbtk. + Copyright 1994, 1995, 1996, 1997, 1998, 1999 + Free Software Foundation, Inc. + + Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support. + Substantially augmented by Martin Hunt, Keith Seitz & Jim Ingham of + Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "inferior.h" +#include "command.h" +#include "source.h" +#include "bfd.h" +#include "symfile.h" +#include "objfiles.h" +#include "target.h" +#include "gdbcore.h" +#include "tracepoint.h" +#include "demangle.h" +#include "frame.h" +#include "tui/tui-file.h" + +#include <sys/stat.h> + +#include <tcl.h> +#include <tk.h> +#include <itcl.h> +#include <tix.h> +#include "guitcl.h" +#include "gdbtk.h" + +#include <signal.h> +#include <fcntl.h> +#include "top.h" +#include <sys/ioctl.h> +#include "gdb_string.h" +#include "dis-asm.h" +#include <stdio.h> +#include "gdbcmd.h" + +#include "annotate.h" +#include <sys/time.h> + +static void setup_architecture_data PARAMS ((void)); +static int tracepoint_exists (char *args); + +/* This structure filled in call_wrapper and passed to + the wrapped call function. + It stores the command pointer and arguments + run in the wrapper function. */ + +struct wrapped_call_args + { + Tcl_Interp *interp; + Tcl_ObjCmdProc *func; + int objc; + Tcl_Obj *CONST * objv; + int val; + }; + +/* These two objects hold boolean true and false, + and are shared by all the list objects that gdb_listfuncs + returns. */ + +static Tcl_Obj *mangled, *not_mangled; + +/* These two control how the GUI behaves when gdb is either tracing or loading. + They are used in this file & gdbtk_hooks.c */ + +int No_Update = 0; +int load_in_progress = 0; + +/* + * This is used in the register fetching routines + */ + +#ifndef INVALID_FLOAT +#define INVALID_FLOAT(x, y) (0 != 0) +#endif + + + +/* This Structure is used in gdb_disassemble. + We need a different sort of line table from the normal one cuz we can't + depend upon implicit line-end pc's for lines to do the + reordering in this function. */ + +struct my_line_entry + { + int line; + CORE_ADDR start_pc; + CORE_ADDR end_pc; + }; + +/* Use this to pass the Tcl Text widget command and the open file + descriptor to the disassembly load command. */ + +struct disassembly_client_data { + FILE *fp; + int file_opened_p; + int widget_line_no; + Tcl_Interp *interp; + char *widget; + Tcl_Obj *result_obj[3]; + char *asm_argv[14]; + char *source_argv[7]; + char *map_arr; + Tcl_DString src_to_line_prefix; + Tcl_DString pc_to_line_prefix; + Tcl_DString line_to_pc_prefix; + Tcl_CmdInfo cmd; +}; + +/* This contains the previous values of the registers, since the last call to + gdb_changed_register_list. */ + +static char *old_regs; + +/* These two lookup tables are used to translate the type & disposition fields + of the breakpoint structure (respectively) into something gdbtk understands. + They are also used in gdbtk-hooks.c */ + +char *bptypes[] = +{"none", "breakpoint", "hw breakpoint", "until", + "finish", "watchpoint", "hw watchpoint", + "read watchpoint", "acc watchpoint", + "longjmp", "longjmp resume", "step resume", + "sigtramp", "watchpoint scope", + "call dummy", "shlib events", "catch load", + "catch unload", "catch fork", "catch vfork", + "catch exec", "catch catch", "catch throw" +}; +char *bpdisp[] = +{"delete", "delstop", "disable", "donttouch"}; + +/* + * These are routines we need from breakpoint.c. + * at some point make these static in breakpoint.c and move GUI code there + */ + +extern struct breakpoint *set_raw_breakpoint (struct symtab_and_line sal); +extern void set_breakpoint_count (int); +extern int breakpoint_count; + +/* This variable determines where memory used for disassembly is read from. + * See note in gdbtk.h for details. + */ +int disassemble_from_exec = -1; + +extern int gdb_variable_init PARAMS ((Tcl_Interp * interp)); + +/* + * Declarations for routines exported from this file + */ + +int Gdbtk_Init (Tcl_Interp * interp); +int call_wrapper PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[])); + +/* + * Declarations for routines used only in this file. + */ + +static int compare_lines PARAMS ((const PTR, const PTR)); +static int comp_files PARAMS ((const void *, const void *)); +static int gdb_actions_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_changed_register_list PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_clear_file PARAMS ((ClientData, Tcl_Interp * interp, int, + Tcl_Obj * CONST[])); +static int gdb_cmd PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_confirm_quit PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_disassemble PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_eval PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_fetch_registers PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_find_file_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_force_quit PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static struct symtab *full_lookup_symtab PARAMS ((char *file)); +static int gdb_get_args_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_get_breakpoint_info PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_get_breakpoint_list PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_get_file_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_get_function_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_get_line_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_get_locals_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_get_mem PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_get_trace_frame_num PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_get_tracepoint_list PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_get_vars_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_immediate_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_listfiles PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_listfuncs PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_loadfile PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_load_disassembly PARAMS ((ClientData clientData, Tcl_Interp + *interp, + int objc, Tcl_Obj *CONST objv[])); +static int gdb_load_info PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_loc PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_path_conv PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_prompt_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_regnames PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_restore_fputs PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_search PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_set_bp PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_set_bp_addr PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_find_bp_at_line PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_find_bp_at_addr PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdb_stop PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_target_has_execution_command PARAMS ((ClientData, + Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_trace_status PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); +static int gdb_tracepoint_exists_command PARAMS ((ClientData, Tcl_Interp *, + int, + Tcl_Obj * CONST objv[])); +static int gdb_get_tracepoint_info PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST objv[])); +static int gdbtk_dis_asm_read_memory PARAMS ((bfd_vma, bfd_byte *, int, + disassemble_info *)); +static void gdbtk_load_source PARAMS ((ClientData clientData, + struct symtab *symtab, + int start_line, int end_line)); +static CORE_ADDR gdbtk_load_asm PARAMS ((ClientData clientData, CORE_ADDR pc, + struct disassemble_info *di)); +static void gdbtk_print_source PARAMS ((ClientData clientData, + struct symtab *symtab, + int start_line, int end_line)); +static CORE_ADDR gdbtk_print_asm PARAMS ((ClientData clientData, CORE_ADDR pc, + struct disassemble_info *di)); +static int gdb_disassemble_driver PARAMS ((CORE_ADDR low, CORE_ADDR high, + int mixed_source_and_assembly, + ClientData clientData, + void (*print_source_fn) (ClientData, struct + symtab *, int, int), + CORE_ADDR (*print_asm_fn) (ClientData, + CORE_ADDR, + struct disassemble_info *))); +static int get_pc_register PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj *CONST [])); +static int gdb_stack PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj *CONST [])); +static int gdb_selected_frame PARAMS ((ClientData clientData, + Tcl_Interp *interp, int argc, + Tcl_Obj *CONST objv[])); +static int gdb_selected_block PARAMS ((ClientData clientData, + Tcl_Interp *interp, int argc, + Tcl_Obj *CONST objv[])); +static int gdb_get_blocks PARAMS ((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); +static int gdb_block_vars PARAMS ((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); +char * get_prompt PARAMS ((void)); +static void get_register PARAMS ((int, void *)); +static void get_register_name PARAMS ((int, void *)); +static int map_arg_registers PARAMS ((int, Tcl_Obj * CONST[], + void (*)(int, void *), void *)); +static int perror_with_name_wrapper PARAMS ((PTR args)); +static void register_changed_p PARAMS ((int, void *)); +static int wrapped_call (PTR opaque_args); +static void get_frame_name PARAMS ((Tcl_Interp * interp, Tcl_Obj * list, + struct frame_info * fi)); +char *pc_function_name PARAMS ((CORE_ADDR pc)); + + +/* Gdbtk_Init + * This loads all the Tcl commands into the Tcl interpreter. + * + * Arguments: + * interp - The interpreter into which to load the commands. + * + * Result: + * A standard Tcl result. + */ + +int +Gdbtk_Init (interp) + Tcl_Interp *interp; +{ + Tcl_CreateObjCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL); + Tcl_CreateObjCommand (interp, "gdb_immediate", call_wrapper, + gdb_immediate_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL); + Tcl_CreateObjCommand (interp, "gdb_path_conv", call_wrapper, gdb_path_conv, + NULL); + Tcl_CreateObjCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles, + NULL); + Tcl_CreateObjCommand (interp, "gdb_listfuncs", call_wrapper, gdb_listfuncs, + NULL); + Tcl_CreateObjCommand (interp, "gdb_get_mem", call_wrapper, gdb_get_mem, + NULL); + Tcl_CreateObjCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL); + Tcl_CreateObjCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, + NULL); + Tcl_CreateObjCommand (interp, "gdb_restore_fputs", call_wrapper, gdb_restore_fputs, + NULL); + Tcl_CreateObjCommand (interp, "gdb_fetch_registers", call_wrapper, + gdb_fetch_registers, NULL); + Tcl_CreateObjCommand (interp, "gdb_changed_register_list", call_wrapper, + gdb_changed_register_list, NULL); + Tcl_CreateObjCommand (interp, "gdb_disassemble", call_wrapper, + gdb_disassemble, NULL); + Tcl_CreateObjCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_breakpoint_list", call_wrapper, + gdb_get_breakpoint_list, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_breakpoint_info", call_wrapper, + gdb_get_breakpoint_info, NULL); + Tcl_CreateObjCommand (interp, "gdb_clear_file", call_wrapper, + gdb_clear_file, NULL); + Tcl_CreateObjCommand (interp, "gdb_confirm_quit", call_wrapper, + gdb_confirm_quit, NULL); + Tcl_CreateObjCommand (interp, "gdb_force_quit", call_wrapper, + gdb_force_quit, NULL); + Tcl_CreateObjCommand (interp, "gdb_target_has_execution", + call_wrapper, + gdb_target_has_execution_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_is_tracing", + call_wrapper, gdb_trace_status, + NULL); + Tcl_CreateObjCommand (interp, "gdb_load_info", call_wrapper, gdb_load_info, + NULL); + Tcl_CreateObjCommand (interp, "gdb_get_locals", call_wrapper, + gdb_get_locals_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_args", call_wrapper, + gdb_get_args_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_function", call_wrapper, + gdb_get_function_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_line", call_wrapper, + gdb_get_line_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_file", call_wrapper, + gdb_get_file_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_tracepoint_exists", + call_wrapper, gdb_tracepoint_exists_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_info", + call_wrapper, gdb_get_tracepoint_info, NULL); + Tcl_CreateObjCommand (interp, "gdb_actions", + call_wrapper, gdb_actions_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_prompt", + call_wrapper, gdb_prompt_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_find_file", + call_wrapper, gdb_find_file_command, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_list", + call_wrapper, gdb_get_tracepoint_list, NULL); + Tcl_CreateObjCommand (interp, "gdb_pc_reg", call_wrapper, get_pc_register, + NULL); + Tcl_CreateObjCommand (interp, "gdb_loadfile", call_wrapper, gdb_loadfile, + NULL); + Tcl_CreateObjCommand (interp, "gdb_load_disassembly", call_wrapper, + gdb_load_disassembly, NULL); + Tcl_CreateObjCommand (gdbtk_interp, "gdb_search", call_wrapper, + gdb_search, NULL); + Tcl_CreateObjCommand (interp, "gdb_set_bp", call_wrapper, gdb_set_bp, NULL); + Tcl_CreateObjCommand (interp, "gdb_set_bp_addr", call_wrapper, + gdb_set_bp_addr, NULL); + Tcl_CreateObjCommand (interp, "gdb_find_bp_at_line", call_wrapper, + gdb_find_bp_at_line, NULL); + Tcl_CreateObjCommand (interp, "gdb_find_bp_at_addr", call_wrapper, + gdb_find_bp_at_addr, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_trace_frame_num", + call_wrapper, gdb_get_trace_frame_num, NULL); + Tcl_CreateObjCommand (interp, "gdb_stack", call_wrapper, gdb_stack, NULL); + Tcl_CreateObjCommand (interp, "gdb_selected_frame", call_wrapper, + gdb_selected_frame, NULL); + Tcl_CreateObjCommand (interp, "gdb_selected_block", call_wrapper, + gdb_selected_block, NULL); + Tcl_CreateObjCommand (interp, "gdb_get_blocks", call_wrapper, + gdb_get_blocks, NULL); + Tcl_CreateObjCommand (interp, "gdb_block_variables", call_wrapper, + gdb_block_vars, NULL); + + Tcl_LinkVar (interp, "gdb_selected_frame_level", + (char *) &selected_frame_level, + TCL_LINK_INT | TCL_LINK_READ_ONLY); + + /* gdb_context is used for debugging multiple threads or tasks */ + Tcl_LinkVar (interp, "gdb_context_id", + (char *) &gdb_context, + TCL_LINK_INT | TCL_LINK_READ_ONLY); + + /* Init variable interface... */ + if (gdb_variable_init (interp) != TCL_OK) + return TCL_ERROR; + + /* Route GDB internal log messages and target output and through + stderr instead of stdout. FIXME: Should have a separate streams + for handling these two types of output. */ + gdb_stdtarg = gdb_stderr; + gdb_stdlog = gdb_stderr; + + /* Register/initialize any architecture specific data */ + setup_architecture_data (); + register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL); + register_gdbarch_swap (NULL, 0, setup_architecture_data); + + /* Determine where to disassemble from */ + Tcl_LinkVar (gdbtk_interp, "disassemble-from-exec", + (char *) &disassemble_from_exec, + TCL_LINK_INT); + + Tcl_PkgProvide (interp, "Gdbtk", GDBTK_VERSION); + return TCL_OK; +} + +/* This routine acts as a top-level for all GDB code called by Tcl/Tk. It + handles cleanups, and uses catch_errors to trap calls to return_to_top_level + (usually via error). + This is necessary in order to prevent a longjmp out of the bowels of Tk, + possibly leaving things in a bad state. Since this routine can be called + recursively, it needs to save and restore the contents of the result_ptr as + necessary. */ + +int +call_wrapper (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct wrapped_call_args wrapped_args; + gdbtk_result new_result, *old_result_ptr; + + old_result_ptr = result_ptr; + result_ptr = &new_result; + result_ptr->obj_ptr = Tcl_NewObj (); + result_ptr->flags = GDBTK_TO_RESULT; + + wrapped_args.func = (Tcl_ObjCmdProc *) clientData; + wrapped_args.interp = interp; + wrapped_args.objc = objc; + wrapped_args.objv = objv; + wrapped_args.val = TCL_OK; + + if (!catch_errors (wrapped_call, &wrapped_args, "", RETURN_MASK_ALL)) + { + + wrapped_args.val = TCL_ERROR; /* Flag an error for TCL */ + + /* Make sure the timer interrupts are turned off. */ + gdbtk_stop_timer (); + + gdb_flush (gdb_stderr); /* Flush error output */ + gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */ + + /* If we errored out here, and the results were going to the + console, then gdbtk_fputs will have gathered the result into the + result_ptr. We also need to echo them out to the console here */ + + gdb_flush (gdb_stderr); /* Flush error output */ + gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */ + + /* In case of an error, we may need to force the GUI into idle + mode because gdbtk_call_command may have bombed out while in + the command routine. */ + + running_now = 0; + Tcl_Eval (interp, "gdbtk_tcl_idle"); + + } + + /* do not suppress any errors -- a remote target could have errored */ + load_in_progress = 0; + + /* + * Now copy the result over to the true Tcl result. If GDBTK_TO_RESULT flag + * bit is set , this just copies a null object over to the Tcl result, + * which is fine because we should reset the result in this case anyway. + */ + if (result_ptr->flags & GDBTK_IN_TCL_RESULT) + { + Tcl_DecrRefCount (result_ptr->obj_ptr); + } + else + { + Tcl_SetObjResult (interp, result_ptr->obj_ptr); + } + + result_ptr = old_result_ptr; + +#ifdef _WIN32 + close_bfds (); +#endif + + return wrapped_args.val; +} + +/* + * This is the wrapper that is passed to catch_errors. + */ + +static int +wrapped_call (opaque_args) + PTR opaque_args; +{ + struct wrapped_call_args *args = (struct wrapped_call_args *) opaque_args; + args->val = (*args->func) (args->func, args->interp, args->objc, args->objv); + return 1; +} + +/* This is a convenience function to sprintf something(s) into a + * new element in a Tcl list object. + */ + +static void +sprintf_append_element_to_obj (Tcl_Obj * objp, char *format,...) +{ + va_list args; + char buf[1024]; + + va_start (args, format); + + vsprintf (buf, format, args); + + Tcl_ListObjAppendElement (NULL, objp, Tcl_NewStringObj (buf, -1)); +} + +/* + * This section contains the commands that control execution. + */ + +/* This implements the tcl command gdb_clear_file. + + * Prepare to accept a new executable file. This is called when we + * want to clear away everything we know about the old file, without + * asking the user. The Tcl code will have already asked the user if + * necessary. After this is called, we should be able to run the + * `file' command without getting any questions. + * + * Arguments: + * None + * Tcl Result: + * None + */ + +static int +gdb_clear_file (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + if (objc != 1) + Tcl_SetStringObj (result_ptr->obj_ptr, + "Wrong number of args, none are allowed.", -1); + + if (inferior_pid != 0 && target_has_execution) + { + if (attach_flag) + target_detach (NULL, 0); + else + target_kill (); + } + + if (target_has_execution) + pop_target (); + + delete_command (NULL, 0); + exec_file_command (NULL, 0); + symbol_file_command (NULL, 0); + + return TCL_OK; +} + +/* This implements the tcl command gdb_confirm_quit + * Ask the user to confirm an exit request. + * + * Arguments: + * None + * Tcl Result: + * A boolean, 1 if the user answered yes, 0 if no. + */ + +static int +gdb_confirm_quit (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int ret; + + if (objc != 1) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "Wrong number of args, should be none.", -1); + return TCL_ERROR; + } + + ret = quit_confirm (); + Tcl_SetBooleanObj (result_ptr->obj_ptr, ret); + return TCL_OK; +} + +/* This implements the tcl command gdb_force_quit + * Quit without asking for confirmation. + * + * Arguments: + * None + * Tcl Result: + * None + */ + +static int +gdb_force_quit (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + if (objc != 1) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "Wrong number of args, should be none.", -1); + return TCL_ERROR; + } + + quit_force ((char *) NULL, 1); + return TCL_OK; +} + +/* Pressing the stop button on the source window should attempt to + * stop the target. If, after some short time, this fails, a dialog + * should appear allowing the user to detach. + * + * The global GDBTK_FORCE_DETACH is set when we wish to detach + * from a target. This value is returned by ui_loop_hook (x_event), + * indicating to callers that they should detach. + * + * Read the comments before x_event to find out how we (try) to keep + * gdbtk alive while some other event loop has stolen control from us. + */ + +/* + * This command implements the tcl command gdb_stop, which + * is used to either stop the target or detach. + * Note that it is assumed that a simulator or native target + * can ALWAYS be stopped. Doing a "detach" on them has no effect. + * + * Arguments: + * None or "detach" + * Tcl Result: + * None + */ + +static int +gdb_stop (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int force = 0; + char *s; + + if (objc > 1) + { + s = Tcl_GetStringFromObj (objv[1], NULL); + if (STREQ (s, "detach")) + force = 1; + } + + if (force) + { + /* Set the "forcibly detach from target" flag. x_event will + return this value to callers when they should forcibly detach. */ + gdbtk_force_detach = 1; + } + else + { + if (target_stop != target_ignore) + target_stop (); + else + quit_flag = 1; /* hope something sees this */ + } + + return TCL_OK; +} + + +/* + * This section contains Tcl commands that are wrappers for invoking + * the GDB command interpreter. + */ + + +/* This implements the tcl command `gdb_eval'. + * It uses the gdb evaluator to return the value of + * an expression in the current language + * + * Tcl Arguments: + * expression - the expression to evaluate. + * Tcl Result: + * The result of the evaluation. + */ + +static int +gdb_eval (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct expression *expr; + struct cleanup *old_chain = NULL; + value_ptr val; + + if (objc != 2) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "wrong # args, should be \"gdb_eval expression\"", -1); + return TCL_ERROR; + } + + expr = parse_expression (Tcl_GetStringFromObj (objv[1], NULL)); + + old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr); + + val = evaluate_expression (expr); + + /* + * Print the result of the expression evaluation. This will go to + * eventually go to gdbtk_fputs, and from there be collected into + * the Tcl result. + */ + + val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), + VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), + gdb_stdout, 0, 0, 0, 0); + + do_cleanups (old_chain); + + return TCL_OK; +} + +/* This implements the tcl command "gdb_cmd". + + * It sends its argument to the GDB command scanner for execution. + * This command will never cause the update, idle and busy hooks to be called + * within the GUI. + * + * Tcl Arguments: + * command - The GDB command to execute + * from_tty - 1 indicates this comes to the console. + * Pass this to the gdb command. + * Tcl Result: + * The output from the gdb command (except for the "load" & "while" + * which dump their output to the console. + */ + +static int +gdb_cmd (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int from_tty = 0; + + if (objc < 2) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args", -1); + return TCL_ERROR; + } + + if (objc == 3) + { + if (Tcl_GetBooleanFromObj (NULL, objv[2], &from_tty) != TCL_OK) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "from_tty must be a boolean.", + -1); + return TCL_ERROR; + } + } + + if (running_now || load_in_progress) + return TCL_OK; + + No_Update = 1; + + /* for the load instruction (and possibly others later) we + set turn off the GDBTK_TO_RESULT flag bit so gdbtk_fputs() + will not buffer all the data until the command is finished. */ + + if ((strncmp ("load ", Tcl_GetStringFromObj (objv[1], NULL), 5) == 0)) + { + result_ptr->flags &= ~GDBTK_TO_RESULT; + load_in_progress = 1; + } + + execute_command (Tcl_GetStringFromObj (objv[1], NULL), from_tty); + + if (load_in_progress) + { + load_in_progress = 0; + result_ptr->flags |= GDBTK_TO_RESULT; + } + + bpstat_do_actions (&stop_bpstat); + + return TCL_OK; +} + +/* + * This implements the tcl command "gdb_immediate" + * + * It does exactly the same thing as gdb_cmd, except NONE of its outut + * is buffered. This will also ALWAYS cause the busy, update, and idle + * hooks to be called, contrasted with gdb_cmd, which NEVER calls them. + * It turns off the GDBTK_TO_RESULT flag, which diverts the result + * to the console window. + * + * Tcl Arguments: + * command - The GDB command to execute + * from_tty - 1 to indicate this is from the console. + * Tcl Result: + * None. + */ + +static int +gdb_immediate_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + + int from_tty = 0; + + if (objc < 2) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args", -1); + return TCL_ERROR; + } + + if (objc == 3) + { + if (Tcl_GetBooleanFromObj (NULL, objv[2], &from_tty) != TCL_OK) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "from_tty must be a boolean.", + -1); + return TCL_ERROR; + } + } + + if (running_now || load_in_progress) + return TCL_OK; + + No_Update = 0; + + result_ptr->flags &= ~GDBTK_TO_RESULT; + + execute_command (Tcl_GetStringFromObj (objv[1], NULL), from_tty); + + bpstat_do_actions (&stop_bpstat); + + result_ptr->flags |= GDBTK_TO_RESULT; + + return TCL_OK; +} + +/* This implements the tcl command "gdb_prompt" + + * It returns the gdb interpreter's prompt. + * + * Tcl Arguments: + * None. + * Tcl Result: + * The prompt. + */ + +static int +gdb_prompt_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + Tcl_SetStringObj (result_ptr->obj_ptr, get_prompt (), -1); + return TCL_OK; +} + + +/* + * This section contains general informational commands. + */ + +/* This implements the tcl command "gdb_target_has_execution" + + * Tells whether the target is executing. + * + * Tcl Arguments: + * None + * Tcl Result: + * A boolean indicating whether the target is executing. + */ + +static int +gdb_target_has_execution_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int result = 0; + + if (target_has_execution && inferior_pid != 0) + result = 1; + + Tcl_SetBooleanObj (result_ptr->obj_ptr, result); + return TCL_OK; +} + +/* This implements the tcl command "gdb_load_info" + + * It returns information about the file about to be downloaded. + * + * Tcl Arguments: + * filename: The file to open & get the info on. + * Tcl Result: + * A list consisting of the name and size of each section. + */ + +static int +gdb_load_info (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + bfd *loadfile_bfd; + struct cleanup *old_cleanups; + asection *s; + Tcl_Obj *ob[2]; + + char *filename = Tcl_GetStringFromObj (objv[1], NULL); + + loadfile_bfd = bfd_openr (filename, gnutarget); + if (loadfile_bfd == NULL) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Open failed", -1); + return TCL_ERROR; + } + old_cleanups = make_cleanup ((make_cleanup_func) bfd_close, loadfile_bfd); + + if (!bfd_check_format (loadfile_bfd, bfd_object)) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Bad Object File", -1); + return TCL_ERROR; + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + for (s = loadfile_bfd->sections; s; s = s->next) + { + if (s->flags & SEC_LOAD) + { + bfd_size_type size = bfd_get_section_size_before_reloc (s); + if (size > 0) + { + ob[0] = Tcl_NewStringObj ((char *) + bfd_get_section_name (loadfile_bfd, s), + -1); + ob[1] = Tcl_NewLongObj ((long) size); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewListObj (2, ob)); + } + } + } + + do_cleanups (old_cleanups); + return TCL_OK; +} + + +/* gdb_get_locals - + * This and gdb_get_locals just call gdb_get_vars_command with the right + * value of clientData. We can't use the client data in the definition + * of the command, because the call wrapper uses this instead... + */ + +static int +gdb_get_locals_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + + return gdb_get_vars_command ((ClientData) 0, interp, objc, objv); + +} + +static int +gdb_get_args_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + + return gdb_get_vars_command ((ClientData) 1, interp, objc, objv); + +} + +/* This implements the tcl commands "gdb_get_locals" and "gdb_get_args" + + * This function sets the Tcl interpreter's result to a list of variable names + * depending on clientData. If clientData is one, the result is a list of + * arguments; zero returns a list of locals -- all relative to the block + * specified as an argument to the command. Valid commands include + * anything decode_line_1 can handle (like "main.c:2", "*0x02020202", + * and "main"). + * + * Tcl Arguments: + * linespec - the linespec defining the scope of the lookup. Empty string + * to use the current block in the innermost frame. + * Tcl Result: + * A list of the locals or args + */ + +static int +gdb_get_vars_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symtabs_and_lines sals; + struct symbol *sym; + struct block *block; + char **canonical, *args; + int i, nsyms, arguments; + + if (objc > 2) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, + "wrong # of args: should be \"", + Tcl_GetStringFromObj (objv[0], NULL), + " [function:line|function|line|*addr]\"", NULL); + return TCL_ERROR; + } + + arguments = (int) clientData; + + /* Initialize the result pointer to an empty list. */ + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + if (objc == 2) + { + args = Tcl_GetStringFromObj (objv[1], NULL); + sals = decode_line_1 (&args, 1, NULL, 0, &canonical); + if (sals.nelts == 0) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "error decoding line", -1); + return TCL_ERROR; + } + + /* Resolve all line numbers to PC's */ + for (i = 0; i < sals.nelts; i++) + resolve_sal_pc (&sals.sals[i]); + + block = block_for_pc (sals.sals[0].pc); + } + else + { + /* Specified currently selected frame */ + if (selected_frame == NULL) + return TCL_OK; + + block = get_frame_block (selected_frame); + } + + while (block != 0) + { + nsyms = BLOCK_NSYMS (block); + for (i = 0; i < nsyms; i++) + { + sym = BLOCK_SYM (block, i); + switch (SYMBOL_CLASS (sym)) + { + default: + case LOC_UNDEF: /* catches errors */ + case LOC_CONST: /* constant */ + case LOC_TYPEDEF: /* local typedef */ + case LOC_LABEL: /* local label */ + case LOC_BLOCK: /* local function */ + case LOC_CONST_BYTES: /* loc. byte seq. */ + case LOC_UNRESOLVED: /* unresolved static */ + case LOC_OPTIMIZED_OUT: /* optimized out */ + break; + case LOC_ARG: /* argument */ + case LOC_REF_ARG: /* reference arg */ + case LOC_REGPARM: /* register arg */ + case LOC_REGPARM_ADDR: /* indirect register arg */ + case LOC_LOCAL_ARG: /* stack arg */ + case LOC_BASEREG_ARG: /* basereg arg */ + if (arguments) + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (SYMBOL_NAME (sym), -1)); + break; + case LOC_LOCAL: /* stack local */ + case LOC_BASEREG: /* basereg local */ + case LOC_STATIC: /* static */ + case LOC_REGISTER: /* register */ + if (!arguments) + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (SYMBOL_NAME (sym), -1)); + break; + } + } + if (BLOCK_FUNCTION (block)) + break; + else + block = BLOCK_SUPERBLOCK (block); + } + + return TCL_OK; +} + +/* This implements the tcl command "gdb_get_line" + + * It returns the linenumber for a given linespec. It will take any spec + * that can be passed to decode_line_1 + * + * Tcl Arguments: + * linespec - the line specification + * Tcl Result: + * The line number for that spec. + */ +static int +gdb_get_line_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symtabs_and_lines sals; + char *args, **canonical; + + if (objc != 2) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, + "wrong # of args: should be \"", + Tcl_GetStringFromObj (objv[0], NULL), + " linespec\"", NULL); + return TCL_ERROR; + } + + args = Tcl_GetStringFromObj (objv[1], NULL); + sals = decode_line_1 (&args, 1, NULL, 0, &canonical); + if (sals.nelts == 1) + { + Tcl_SetIntObj (result_ptr->obj_ptr, sals.sals[0].line); + return TCL_OK; + } + + Tcl_SetStringObj (result_ptr->obj_ptr, "N/A", -1); + return TCL_OK; + +} + +/* This implements the tcl command "gdb_get_file" + + * It returns the file containing a given line spec. + * + * Tcl Arguments: + * linespec - The linespec to look up + * Tcl Result: + * The file containing it. + */ + +static int +gdb_get_file_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symtabs_and_lines sals; + char *args, **canonical; + + if (objc != 2) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, + "wrong # of args: should be \"", + Tcl_GetStringFromObj (objv[0], NULL), + " linespec\"", NULL); + return TCL_ERROR; + } + + args = Tcl_GetStringFromObj (objv[1], NULL); + sals = decode_line_1 (&args, 1, NULL, 0, &canonical); + if (sals.nelts == 1) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + sals.sals[0].symtab->filename, -1); + return TCL_OK; + } + + Tcl_SetStringObj (result_ptr->obj_ptr, "N/A", -1); + return TCL_OK; +} + +/* This implements the tcl command "gdb_get_function" + + * It finds the function containing the given line spec. + * + * Tcl Arguments: + * linespec - The line specification + * Tcl Result: + * The function that contains it, or "N/A" if it is not in a function. + */ +static int +gdb_get_function_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char *function; + struct symtabs_and_lines sals; + char *args, **canonical; + + if (objc != 2) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, + "wrong # of args: should be \"", + Tcl_GetStringFromObj (objv[0], NULL), + " linespec\"", NULL); + return TCL_ERROR; + } + + args = Tcl_GetStringFromObj (objv[1], NULL); + sals = decode_line_1 (&args, 1, NULL, 0, &canonical); + if (sals.nelts == 1) + { + resolve_sal_pc (&sals.sals[0]); + function = pc_function_name (sals.sals[0].pc); + Tcl_SetStringObj (result_ptr->obj_ptr, function, -1); + return TCL_OK; + } + + Tcl_SetStringObj (result_ptr->obj_ptr, "N/A", -1); + return TCL_OK; +} + +/* This implements the tcl command "gdb_find_file" + + * It searches the symbol tables to get the full pathname to a file. + * + * Tcl Arguments: + * filename: the file name to search for. + * Tcl Result: + * The full path to the file, or an empty string if the file is not + * found. + */ + +static int +gdb_find_file_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char *filename = NULL; + struct symtab *st; + + if (objc != 2) + { + Tcl_WrongNumArgs (interp, 1, objv, "filename"); + return TCL_ERROR; + } + + st = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL)); + if (st) + filename = st->fullname; + + if (filename == NULL) + Tcl_SetStringObj (result_ptr->obj_ptr, "", 0); + else + Tcl_SetStringObj (result_ptr->obj_ptr, filename, -1); + + return TCL_OK; +} + +/* This implements the tcl command "gdb_listfiles" + + * This lists all the files in the current executible. + * + * Note that this currently pulls in all sorts of filenames + * that aren't really part of the executable. It would be + * best if we could check each file to see if it actually + * contains executable lines of code, but we can't do that + * with psymtabs. + * + * Arguments: + * ?pathname? - If provided, only files which match pathname + * (up to strlen(pathname)) are included. THIS DOES NOT + * CURRENTLY WORK BECAUSE PARTIAL_SYMTABS DON'T SUPPLY + * THE FULL PATHNAME!!! + * + * Tcl Result: + * A list of all matching files. + */ +static int +gdb_listfiles (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct objfile *objfile; + struct partial_symtab *psymtab; + struct symtab *symtab; + char *lastfile, *pathname = NULL, **files; + int files_size; + int i, numfiles = 0, len = 0; + + files_size = 1000; + files = (char **) xmalloc (sizeof (char *) * files_size); + + if (objc > 2) + { + Tcl_WrongNumArgs (interp, 1, objv, "Usage: gdb_listfiles ?pathname?"); + return TCL_ERROR; + } + else if (objc == 2) + pathname = Tcl_GetStringFromObj (objv[1], &len); + + ALL_PSYMTABS (objfile, psymtab) + { + if (numfiles == files_size) + { + files_size = files_size * 2; + files = (char **) xrealloc (files, sizeof (char *) * files_size); + } + if (psymtab->filename) + { + if (!len || !strncmp (pathname, psymtab->filename, len) + || !strcmp (psymtab->filename, basename (psymtab->filename))) + { + files[numfiles++] = basename (psymtab->filename); + } + } + } + + ALL_SYMTABS (objfile, symtab) + { + if (numfiles == files_size) + { + files_size = files_size * 2; + files = (char **) xrealloc (files, sizeof (char *) * files_size); + } + if (symtab->filename && symtab->linetable && symtab->linetable->nitems) + { + if (!len || !strncmp (pathname, symtab->filename, len) + || !strcmp (symtab->filename, basename (symtab->filename))) + { + files[numfiles++] = basename (symtab->filename); + } + } + } + + qsort (files, numfiles, sizeof (char *), comp_files); + + lastfile = ""; + + /* Discard the old result pointer, in case it has accumulated anything + and set it to a new list object */ + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + for (i = 0; i < numfiles; i++) + { + if (strcmp (files[i], lastfile)) + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (files[i], -1)); + lastfile = files[i]; + } + + free (files); + return TCL_OK; +} + +static int +comp_files (file1, file2) + const void *file1, *file2; +{ + return strcmp (*(char **) file1, *(char **) file2); +} + + +/* This implements the tcl command "gdb_search" + + + * Tcl Arguments: + * option - One of "functions", "variables" or "types" + * regexp - The regular expression to look for. + * Then, optionally: + * -files fileList + * -static 1/0 + * -filename 1/0 + * Tcl Result: + * A list of all the matches found. Optionally, if -filename is set to 1, + * then the output is a list of two element lists, with the symbol first, + * and the file in which it is found second. + */ + +static int +gdb_search (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symbol_search *ss = NULL; + struct symbol_search *p; + struct cleanup *old_chain = NULL; + Tcl_Obj *CONST * switch_objv; + int index, switch_objc, i, show_files = 0; + namespace_enum space = 0; + char *regexp; + int static_only, nfiles; + Tcl_Obj **file_list; + char **files; + static char *search_options[] = + {"functions", "variables", "types", (char *) NULL}; + static char *switches[] = + {"-files", "-filename", "-static", (char *) NULL}; + enum search_opts + { + SEARCH_FUNCTIONS, SEARCH_VARIABLES, SEARCH_TYPES + }; + enum switches_opts + { + SWITCH_FILES, SWITCH_FILENAME, SWITCH_STATIC_ONLY + }; + + if (objc < 3) + { + Tcl_WrongNumArgs (interp, 1, objv, "option regexp ?arg ...?"); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj (interp, objv[1], search_options, "option", 0, + &index) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + /* Unfortunately, we cannot teach search_symbols to search on + multiple regexps, so we have to do a two-tier search for + any searches which choose to narrow the playing field. */ + switch ((enum search_opts) index) + { + case SEARCH_FUNCTIONS: + space = FUNCTIONS_NAMESPACE; + break; + case SEARCH_VARIABLES: + space = VARIABLES_NAMESPACE; + break; + case SEARCH_TYPES: + space = TYPES_NAMESPACE; + break; + } + + regexp = Tcl_GetStringFromObj (objv[2], NULL); + /* Process any switches that refine the search */ + switch_objc = objc - 3; + switch_objv = objv + 3; + + static_only = 0; + nfiles = 0; + files = (char **) NULL; + while (switch_objc > 0) + { + if (Tcl_GetIndexFromObj (interp, switch_objv[0], switches, + "option", 0, &index) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + switch ((enum switches_opts) index) + { + case SWITCH_FILENAME: + { + if (switch_objc < 2) + { + Tcl_WrongNumArgs (interp, 3, objv, + "?-files fileList -filename 1|0 -static 1|0?"); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + if (Tcl_GetBooleanFromObj (interp, switch_objv[1], &show_files) + != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + switch_objc--; + switch_objv++; + } + break; + case SWITCH_FILES: + { + int result; + if (switch_objc < 2) + { + Tcl_WrongNumArgs (interp, 3, objv, + "?-files fileList -filename 1|0 -static 1|0?"); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + result = Tcl_ListObjGetElements (interp, switch_objv[1], + &nfiles, &file_list); + if (result != TCL_OK) + return result; + + files = (char **) xmalloc (nfiles * sizeof (char *)); + for (i = 0; i < nfiles; i++) + files[i] = Tcl_GetStringFromObj (file_list[i], NULL); + switch_objc--; + switch_objv++; + } + break; + case SWITCH_STATIC_ONLY: + if (switch_objc < 2) + { + Tcl_WrongNumArgs (interp, 3, objv, + "?-files fileList -filename 1|0 -static 1|0?"); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + if (Tcl_GetBooleanFromObj (interp, switch_objv[1], &static_only) + != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + switch_objc--; + switch_objv++; + } + switch_objc--; + switch_objv++; + } + + search_symbols (regexp, space, nfiles, files, &ss); + if (ss != NULL) + old_chain = make_cleanup ((make_cleanup_func) free_search_symbols, ss); + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + for (p = ss; p != NULL; p = p->next) + { + Tcl_Obj *elem; + + if (static_only && p->block != STATIC_BLOCK) + continue; + + /* Strip off some C++ special symbols, like RTTI and global + constructors/destructors. */ + if ((p->symbol != NULL && !STREQN (SYMBOL_NAME (p->symbol), "__tf", 4) + && !STREQN (SYMBOL_NAME (p->symbol), "_GLOBAL_", 8)) + || p->msymbol != NULL) + { + elem = Tcl_NewListObj (0, NULL); + + if (p->msymbol == NULL) + Tcl_ListObjAppendElement (interp, elem, + Tcl_NewStringObj (SYMBOL_SOURCE_NAME (p->symbol), -1)); + else + Tcl_ListObjAppendElement (interp, elem, + Tcl_NewStringObj (SYMBOL_SOURCE_NAME (p->msymbol), -1)); + + if (show_files) + { + if ((p->symtab != NULL) && (p->symtab->filename != NULL)) + { + Tcl_ListObjAppendElement (interp, elem, Tcl_NewStringObj + (p->symtab->filename, -1)); + } + else + { + Tcl_ListObjAppendElement (interp, elem, + Tcl_NewStringObj ("", 0)); + } + } + + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, elem); + } + } + + if (ss != NULL) + do_cleanups (old_chain); + + return TCL_OK; +} + +/* This implements the tcl command gdb_listfuncs + + * It lists all the functions defined in a given file + * + * Arguments: + * file - the file to look in + * Tcl Result: + * A list of two element lists, the first element is + * the symbol name, and the second is a boolean indicating + * whether the symbol is demangled (1 for yes). + */ + +static int +gdb_listfuncs (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symtab *symtab; + struct blockvector *bv; + struct block *b; + struct symbol *sym; + int i, j; + Tcl_Obj *funcVals[2]; + + if (objc != 2) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args", -1); + } + + symtab = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL)); + if (!symtab) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "No such file", -1); + return TCL_ERROR; + } + + if (mangled == NULL) + { + mangled = Tcl_NewBooleanObj (1); + not_mangled = Tcl_NewBooleanObj (0); + Tcl_IncrRefCount (mangled); + Tcl_IncrRefCount (not_mangled); + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + bv = BLOCKVECTOR (symtab); + for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++) + { + b = BLOCKVECTOR_BLOCK (bv, i); + /* Skip the sort if this block is always sorted. */ + if (!BLOCK_SHOULD_SORT (b)) + sort_block_syms (b); + for (j = 0; j < BLOCK_NSYMS (b); j++) + { + sym = BLOCK_SYM (b, j); + if (SYMBOL_CLASS (sym) == LOC_BLOCK) + { + + char *name = SYMBOL_DEMANGLED_NAME (sym); + + if (name) + { + /* strip out "global constructors" and + * "global destructors" + * because we aren't interested in them. */ + + if (strncmp (name, "global ", 7)) + { + /* If the function is overloaded, + * print out the functions + * declaration, not just its name. */ + + funcVals[0] = Tcl_NewStringObj (name, -1); + funcVals[1] = mangled; + } + else + continue; + + } + else + { + funcVals[0] = Tcl_NewStringObj (SYMBOL_NAME (sym), -1); + funcVals[1] = not_mangled; + } + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewListObj (2, funcVals)); + } + } + } + return TCL_OK; +} + + +/* + * This section contains all the commands that act on the registers: + */ + +/* This is a sort of mapcar function for operations on registers */ + +static int +map_arg_registers (objc, objv, func, argp) + int objc; + Tcl_Obj *CONST objv[]; + void (*func) PARAMS ((int regnum, void *argp)); + void *argp; +{ + int regnum, numregs; + + /* Note that the test for a valid register must include checking the + REGISTER_NAME because NUM_REGS may be allocated for the union of + the register sets within a family of related processors. In this + case, some entries of REGISTER_NAME will change depending upon + the particular processor being debugged. */ + + numregs = ARCH_NUM_REGS; + + if (objc == 0) /* No args, just do all the regs */ + { + for (regnum = 0; + regnum < numregs; + regnum++) + { + if (REGISTER_NAME (regnum) == NULL + || *(REGISTER_NAME (regnum)) == '\0') + continue; + + func (regnum, argp); + } + + return TCL_OK; + } + + /* Else, list of register #s, just do listed regs */ + for (; objc > 0; objc--, objv++) + { + if (Tcl_GetIntFromObj (NULL, *objv, ®num) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + if (regnum >= 0 + && regnum < numregs + && REGISTER_NAME (regnum) != NULL + && *REGISTER_NAME (regnum) != '\000') + func (regnum, argp); + else + { + Tcl_SetStringObj (result_ptr->obj_ptr, "bad register number", -1); + return TCL_ERROR; + } + } + + return TCL_OK; +} + +/* This implements the TCL command `gdb_restore_fputs' + It sets the fputs_unfiltered hook back to gdbtk_fputs. + Its sole reason for being is that sometimes we move the + fputs hook out of the way to specially trap output, and if + we get an error which we weren't expecting, it won't get put + back, so we run this at idle time as insurance. + */ + +static int +gdb_restore_fputs (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + fputs_unfiltered_hook = gdbtk_fputs; + return TCL_OK; +} + +/* This implements the TCL command `gdb_regnames', which returns a list of + all of the register names. */ + +static int +gdb_regnames (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + objc--; + objv++; + + return map_arg_registers (objc, objv, get_register_name, NULL); +} + +static void +get_register_name (regnum, argp) + int regnum; + void *argp; /* Ignored */ +{ + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (REGISTER_NAME (regnum), -1)); +} + +/* This implements the tcl command gdb_fetch_registers + * Pass it a list of register names, and it will + * return their values as a list. + * + * Tcl Arguments: + * format: The format string for printing the values + * args: the registers to look for + * Tcl Result: + * A list of their values. + */ + +static int +gdb_fetch_registers (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int format, result; + + if (objc < 2) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "wrong # args, should be gdb_fetch_registers format ?register1 register2 ...?", -1); + } + objc -= 2; + objv++; + format = *(Tcl_GetStringFromObj (objv[0], NULL)); + objv++; + + + result_ptr->flags |= GDBTK_MAKES_LIST; /* Output the results as a list */ + result = map_arg_registers (objc, objv, get_register, (void *) format); + result_ptr->flags &= ~GDBTK_MAKES_LIST; + + return result; +} + +static void +get_register (regnum, fp) + int regnum; + void *fp; +{ + char raw_buffer[MAX_REGISTER_RAW_SIZE]; + char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; + int format = (int) fp; + int optim; + + if (format == 'N') + format = 0; + + /* read_relative_register_raw_bytes returns a virtual frame pointer + (FRAME_FP (selected_frame)) if regnum == FP_REGNUM instead + of the real contents of the register. To get around this, + use get_saved_register instead. */ + get_saved_register (raw_buffer, &optim, (CORE_ADDR *) NULL, selected_frame, + regnum, (enum lval_type *) NULL); + if (optim) + { + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj ("Optimized out", -1)); + return; + } + + /* Convert raw data to virtual format if necessary. */ + + if (REGISTER_CONVERTIBLE (regnum)) + { + REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), + raw_buffer, virtual_buffer); + } + else + memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum)); + + if (format == 'r') + { + int j; + char *ptr, buf[1024]; + + strcpy (buf, "0x"); + ptr = buf + 2; + for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++) + { + register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j + : REGISTER_RAW_SIZE (regnum) - 1 - j; + sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]); + ptr += 2; + } + fputs_filtered (buf, gdb_stdout); + } + else + val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, 0, + gdb_stdout, format, 1, 0, Val_pretty_default); + +} + +/* This implements the tcl command get_pc_reg + * It returns the value of the PC register + * + * Tcl Arguments: + * None + * Tcl Result: + * The value of the pc register. + */ + +static int +get_pc_register (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char buff[64]; + + sprintf (buff, "0x%llx", (long long) read_register (PC_REGNUM)); + Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); + return TCL_OK; +} + +/* This implements the tcl command "gdb_changed_register_list" + * It takes a list of registers, and returns a list of + * the registers on that list that have changed since the last + * time the proc was called. + * + * Tcl Arguments: + * A list of registers. + * Tcl Result: + * A list of changed registers. + */ + +static int +gdb_changed_register_list (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + objc--; + objv++; + + return map_arg_registers (objc, objv, register_changed_p, NULL); +} + +static void +register_changed_p (regnum, argp) + int regnum; + void *argp; /* Ignored */ +{ + char raw_buffer[MAX_REGISTER_RAW_SIZE]; + + if (read_relative_register_raw_bytes (regnum, raw_buffer)) + return; + + if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, + REGISTER_RAW_SIZE (regnum)) == 0) + return; + + /* Found a changed register. Save new value and return its number. */ + + memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer, + REGISTER_RAW_SIZE (regnum)); + + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewIntObj (regnum)); +} + +/* + * This section contains the commands that deal with tracepoints: + */ + +/* return a list of all tracepoint numbers in interpreter */ +static int +gdb_get_tracepoint_list (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct tracepoint *tp; + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + ALL_TRACEPOINTS (tp) + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewIntObj (tp->number)); + + return TCL_OK; +} + +/* returns -1 if not found, tracepoint # if found */ +static int +tracepoint_exists (char *args) +{ + struct tracepoint *tp; + char **canonical; + struct symtabs_and_lines sals; + char *file = NULL; + int result = -1; + + sals = decode_line_1 (&args, 1, NULL, 0, &canonical); + if (sals.nelts == 1) + { + resolve_sal_pc (&sals.sals[0]); + file = xmalloc (strlen (sals.sals[0].symtab->dirname) + + strlen (sals.sals[0].symtab->filename) + 1); + if (file != NULL) + { + strcpy (file, sals.sals[0].symtab->dirname); + strcat (file, sals.sals[0].symtab->filename); + + ALL_TRACEPOINTS (tp) + { + if (tp->address == sals.sals[0].pc) + result = tp->number; +#if 0 + /* Why is this here? This messes up assembly traces */ + else if (tp->source_file != NULL + && strcmp (tp->source_file, file) == 0 + && sals.sals[0].line == tp->line_number) + result = tp->number; +#endif + } + } + } + if (file != NULL) + free (file); + return result; +} + +static int +gdb_tracepoint_exists_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char *args; + + if (objc != 2) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, + "wrong # of args: should be \"", + Tcl_GetStringFromObj (objv[0], NULL), + " function:line|function|line|*addr\"", NULL); + return TCL_ERROR; + } + + args = Tcl_GetStringFromObj (objv[1], NULL); + + Tcl_SetIntObj (result_ptr->obj_ptr, tracepoint_exists (args)); + return TCL_OK; +} + +static int +gdb_get_tracepoint_info (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symtab_and_line sal; + int tpnum; + struct tracepoint *tp; + struct action_line *al; + Tcl_Obj *action_list; + char *filename, *funcname, *fname; + + if (objc != 2) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args", -1); + return TCL_ERROR; + } + + if (Tcl_GetIntFromObj (NULL, objv[1], &tpnum) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + ALL_TRACEPOINTS (tp) + if (tp->number == tpnum) + break; + + if (tp == NULL) + { + char buff[64]; + sprintf (buff, "Tracepoint #%d does not exist", tpnum); + Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); + return TCL_ERROR; + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + sal = find_pc_line (tp->address, 0); + filename = symtab_to_filename (sal.symtab); + if (filename == NULL) + filename = "N/A"; + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (filename, -1)); + + funcname = pc_function_name (tp->address); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, Tcl_NewStringObj + (funcname, -1)); + + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewIntObj (sal.line)); + { + char *tmp; + asprintf (&tmp, "0x%s", paddr_nz (tp->address)); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (tmp, -1)); + free (tmp); + } + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewIntObj (tp->enabled)); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewIntObj (tp->pass_count)); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewIntObj (tp->step_count)); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewIntObj (tp->thread)); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewIntObj (tp->hit_count)); + + /* Append a list of actions */ + action_list = Tcl_NewObj (); + for (al = tp->actions; al != NULL; al = al->next) + { + Tcl_ListObjAppendElement (interp, action_list, + Tcl_NewStringObj (al->action, -1)); + } + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, action_list); + + return TCL_OK; +} + + +static int +gdb_trace_status (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int result = 0; + + if (trace_running_p) + result = 1; + + Tcl_SetIntObj (result_ptr->obj_ptr, result); + return TCL_OK; +} + + + +static int +gdb_get_trace_frame_num (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + if (objc != 1) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, + "wrong # of args: should be \"", + Tcl_GetStringFromObj (objv[0], NULL), + " linespec\"", NULL); + return TCL_ERROR; + } + + Tcl_SetIntObj (result_ptr->obj_ptr, get_traceframe_number ()); + return TCL_OK; + +} + +/* This implements the tcl command gdb_actions + * It sets actions for a given tracepoint. + * + * Tcl Arguments: + * number: the tracepoint in question + * actions: the actions to add to this tracepoint + * Tcl Result: + * None. + */ + +static int +gdb_actions_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct tracepoint *tp; + Tcl_Obj **actions; + int nactions, i, len; + char *number, *args, *action; + long step_count; + struct action_line *next = NULL, *temp; + enum actionline_type linetype; + + if (objc != 3) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, + "wrong # args: should be: \"", + Tcl_GetStringFromObj (objv[0], NULL), + " number actions\"", NULL); + return TCL_ERROR; + } + + args = number = Tcl_GetStringFromObj (objv[1], NULL); + tp = get_tracepoint_by_number (&args, 0, 0); + if (tp == NULL) + { + Tcl_AppendStringsToObj (result_ptr->obj_ptr, "Tracepoint \"", + number, "\" does not exist", NULL); + return TCL_ERROR; + } + + /* Free any existing actions */ + if (tp->actions != NULL) + free_actions (tp); + + step_count = 0; + + Tcl_ListObjGetElements (interp, objv[2], &nactions, &actions); + + /* Add the actions to the tracepoint */ + for (i = 0; i < nactions; i++) + { + temp = xmalloc (sizeof (struct action_line)); + temp->next = NULL; + action = Tcl_GetStringFromObj (actions[i], &len); + temp->action = savestring (action, len); + + linetype = validate_actionline (&(temp->action), tp); + + if (linetype == BADLINE) + { + free (temp); + continue; + } + + if (next == NULL) + { + tp->actions = temp; + next = temp; + } + else + { + next->next = temp; + next = temp; + } + } + + return TCL_OK; +} + +/* + * This section has commands that handle source disassembly. + */ +/* This implements the tcl command gdb_disassemble. It is no longer + * used in GDBTk, we use gdb_load_disassembly, but I kept it around in + * case other folks want it. + * + * Arguments: + * source_with_assm - must be "source" or "nosource" + * low_address - the address from which to start disassembly + * ?hi_address? - the address to which to disassemble, defaults + * to the end of the function containing low_address. + * Tcl Result: + * The disassembled code is passed to fputs_unfiltered, so it + * either goes to the console if result_ptr->obj_ptr is NULL or to + * the Tcl result. + */ + +static int +gdb_disassemble (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + CORE_ADDR low, high; + char *arg_ptr; + int mixed_source_and_assembly; + + if (objc != 3 && objc != 4) + error ("wrong # args"); + + arg_ptr = Tcl_GetStringFromObj (objv[1], NULL); + if (*arg_ptr == 's' && strcmp (arg_ptr, "source") == 0) + mixed_source_and_assembly = 1; + else if (*arg_ptr == 'n' && strcmp (arg_ptr, "nosource") == 0) + mixed_source_and_assembly = 0; + else + error ("First arg must be 'source' or 'nosource'"); + + low = parse_and_eval_address (Tcl_GetStringFromObj (objv[2], NULL)); + + if (objc == 3) + { + if (find_pc_partial_function (low, NULL, &low, &high) == 0) + error ("No function contains specified address"); + } + else + high = parse_and_eval_address (Tcl_GetStringFromObj (objv[3], NULL)); + + return gdb_disassemble_driver (low, high, mixed_source_and_assembly, NULL, + gdbtk_print_source, gdbtk_print_asm); + +} + +/* This implements the tcl command gdb_load_disassembly + * + * Arguments: + * widget - the name of a text widget into which to load the data + * source_with_assm - must be "source" or "nosource" + * low_address - the address from which to start disassembly + * ?hi_address? - the address to which to disassemble, defaults + * to the end of the function containing low_address. + * Tcl Result: + * The text widget is loaded with the data, and a list is returned. + * The first element of the list is a two element list containing the + * real low & high elements, the rest is a mapping between line number + * in the text widget, and either the source line number of that line, + * if it is a source line, or the assembly address. You can distinguish + * between the two, because the address will start with 0x... + */ + +static int +gdb_load_disassembly (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + CORE_ADDR low, high; + struct disassembly_client_data client_data; + int mixed_source_and_assembly, ret_val, i; + char *widget; + char *arg_ptr; + char *map_name; + + if (objc != 6 && objc != 7) { + Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args, should be: widget [source|nosource] map_arr index_prefix low_address ?hi_address", -1); + return TCL_ERROR; + } + + client_data.widget = Tcl_GetStringFromObj (objv[1], NULL); + if ( Tk_NameToWindow (interp, client_data.widget, + Tk_MainWindow (interp)) == NULL) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Invalid widget name.", -1); + return TCL_ERROR; + } + + if (!Tcl_GetCommandInfo (interp, client_data.widget, &client_data.cmd)) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Can't get widget command info", + -1); + return TCL_ERROR; + } + + arg_ptr = Tcl_GetStringFromObj (objv[2], NULL); + if (*arg_ptr == 's' && strcmp (arg_ptr, "source") == 0) + mixed_source_and_assembly = 1; + else if (*arg_ptr == 'n' && strcmp (arg_ptr, "nosource") == 0) + mixed_source_and_assembly = 0; + else + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "Second arg must be 'source' or 'nosource'", -1); + return TCL_ERROR; + } + + /* As we populate the text widget, we will also create an array in the + caller's scope. The name is given by objv[3]. + Each source line gets an entry or the form: + array($prefix,srcline=$src_line_no) = $widget_line_no + + Each assembly line gets two entries of the form: + array($prefix,pc=$pc) = $widget_line_no + array($prefix,line=$widget_line_no) = $src_line_no + + Where prefix is objv[4]. + */ + + map_name = Tcl_GetStringFromObj (objv[3], NULL); + + if (*map_name != '\0') + { + char *prefix; + int prefix_len; + + client_data.map_arr = "map_array"; + if (Tcl_UpVar (interp, "1", map_name, client_data.map_arr, 0) != TCL_OK) { + Tcl_SetStringObj (result_ptr->obj_ptr, "Can't link map array.", -1); + return TCL_ERROR; + } + + prefix = Tcl_GetStringFromObj (objv[4], &prefix_len); + + Tcl_DStringInit(&client_data.src_to_line_prefix); + Tcl_DStringAppend (&client_data.src_to_line_prefix, + prefix, prefix_len); + Tcl_DStringAppend (&client_data.src_to_line_prefix, ",srcline=", + sizeof (",srcline=") - 1); + + Tcl_DStringInit(&client_data.pc_to_line_prefix); + Tcl_DStringAppend (&client_data.pc_to_line_prefix, + prefix, prefix_len); + Tcl_DStringAppend (&client_data.pc_to_line_prefix, ",pc=", + sizeof (",pc=") - 1); + + Tcl_DStringInit(&client_data.line_to_pc_prefix); + Tcl_DStringAppend (&client_data.line_to_pc_prefix, + prefix, prefix_len); + Tcl_DStringAppend (&client_data.line_to_pc_prefix, ",line=", + sizeof (",line=") - 1); + + } + else + { + client_data.map_arr = ""; + } + + /* Now parse the addresses */ + + low = parse_and_eval_address (Tcl_GetStringFromObj (objv[5], NULL)); + + if (objc == 6) + { + if (find_pc_partial_function (low, NULL, &low, &high) == 0) + error ("No function contains specified address"); + } + else + high = parse_and_eval_address (Tcl_GetStringFromObj (objv[6], NULL)); + + + /* Setup the client_data structure, and call the driver function. */ + + client_data.file_opened_p = 0; + client_data.widget_line_no = 0; + client_data.interp = interp; + for (i = 0; i < 3; i++) + { + client_data.result_obj[i] = Tcl_NewObj(); + Tcl_IncrRefCount (client_data.result_obj[i]); + } + + /* Fill up the constant parts of the argv structures */ + client_data.asm_argv[0] = client_data.widget; + client_data.asm_argv[1] = "insert"; + client_data.asm_argv[2] = "end"; + client_data.asm_argv[3] = "-\t"; + client_data.asm_argv[4] = "break_rgn_tag"; + /* client_data.asm_argv[5] = address; */ + client_data.asm_argv[6] = "break_rgn_tag"; + /* client_data.asm_argv[7] = offset; */ + client_data.asm_argv[8] = "break_rgn_tag"; + client_data.asm_argv[9] = ":\t\t"; + client_data.asm_argv[10] = "source_tag"; + /* client_data.asm_argv[11] = code; */ + client_data.asm_argv[12] = "source_tag"; + client_data.asm_argv[13] = "\n"; + + if (mixed_source_and_assembly) + { + client_data.source_argv[0] = client_data.widget; + client_data.source_argv[1] = "insert"; + client_data.source_argv[2] = "end"; + /* client_data.source_argv[3] = line_number; */ + client_data.source_argv[4] = ""; + /* client_data.source_argv[5] = line; */ + client_data.source_argv[6] = "source_tag"; + } + + ret_val = gdb_disassemble_driver (low, high, mixed_source_and_assembly, + (ClientData) &client_data, + gdbtk_load_source, gdbtk_load_asm); + + /* Now clean up the opened file, and the Tcl data structures */ + + if (client_data.file_opened_p == 1) { + fclose(client_data.fp); + } + if (*client_data.map_arr != '\0') + { + Tcl_DStringFree(&client_data.src_to_line_prefix); + Tcl_DStringFree(&client_data.pc_to_line_prefix); + Tcl_DStringFree(&client_data.line_to_pc_prefix); + } + + for (i = 0; i < 3; i++) + { + Tcl_DecrRefCount (client_data.result_obj[i]); + } + + /* Finally, if we were successful, stick the low & high addresses + into the Tcl result. */ + + if (ret_val == TCL_OK) { + char buffer[256]; + Tcl_Obj *limits_obj[2]; + + sprintf (buffer, "0x%s", paddr_nz (low)); + limits_obj[0] = Tcl_NewStringObj (buffer, -1); + + sprintf (buffer, "0x%s", paddr_nz (high)); + limits_obj[1] = Tcl_NewStringObj (buffer, -1); + + Tcl_DecrRefCount (result_ptr->obj_ptr); + result_ptr->obj_ptr = Tcl_NewListObj (2, limits_obj); + + } + return ret_val; + +} + +static void +gdbtk_load_source (ClientData clientData, struct symtab *symtab, int + start_line, int end_line) +{ + struct disassembly_client_data *client_data = + (struct disassembly_client_data *) clientData; + char buffer[18]; + int index_len; + + index_len = Tcl_DStringLength (&client_data->src_to_line_prefix); + + if (client_data->file_opened_p == 1) + { + char **text_argv; + char line[10000], line_number[18]; + int found_carriage_return = 1; + + /* First do some sanity checks on the requested lines */ + + if (start_line < 1 + || end_line < start_line || end_line > symtab->nlines) + { + return; + } + + line_number[0] = '\t'; + line[0] = '\t'; + + text_argv = client_data->source_argv; + + text_argv[3] = line_number; + text_argv[5] = line; + + if (fseek (client_data->fp, symtab->line_charpos[start_line - 1], + SEEK_SET) < 0) + { + fclose(client_data->fp); + client_data->file_opened_p = -1; + return; + } + + for (; start_line < end_line; start_line++) + { + if (!fgets (line + 1, 9980, client_data->fp)) + { + fclose(client_data->fp); + client_data->file_opened_p = -1; + return; + } + + client_data->widget_line_no++; + + sprintf (line_number + 1, "%d", start_line); + + if (found_carriage_return) { + char *p; + + p = strrchr(line, '\0') - 2; + if (*p == '\r') { + *p = '\n'; + *(p + 1) = '\0'; + } else { + found_carriage_return = 0; + } + } + + /* Run the command, then add an entry to the map array in + the caller's scope, if requested. */ + + client_data->cmd.proc (client_data->cmd.clientData, + client_data->interp, 7, text_argv); + + if (*client_data->map_arr != '\0') + { + + Tcl_DStringAppend (&client_data->src_to_line_prefix, + line_number + 1, -1); + + /* FIXME: Convert to Tcl_SetVar2Ex when we move to 8.2. This + will allow us avoid converting widget_line_no into a string. */ + + sprintf (buffer, "%d", client_data->widget_line_no); + + Tcl_SetVar2 (client_data->interp, client_data->map_arr, + Tcl_DStringValue (&client_data->src_to_line_prefix), + buffer, 0); + + Tcl_DStringSetLength (&client_data->src_to_line_prefix, index_len); + } + } + + } + else if (!client_data->file_opened_p) + { + int fdes; + /* The file is not yet open, try to open it, then print the + first line. If we fail, set FILE_OPEN_P to -1. */ + + fdes = open_source_file (symtab); + if (fdes < 0) + { + client_data->file_opened_p = -1; + } + else + { + /* FIXME: Convert to a Tcl File Channel and read from there. + This will allow us to get the line endings and conversion + to UTF8 right automatically when we move to 8.2. + Need a Cygwin call to convert a file descriptor to the native + Windows handler to do this. */ + + client_data->file_opened_p = 1; + client_data->fp = fdopen (fdes, FOPEN_RB); + clearerr (client_data->fp); + + if (symtab->line_charpos == 0) + find_source_lines (symtab, fdes); + + /* We are called with an actual load request, so call ourselves + to load the first line. */ + + gdbtk_load_source (clientData, symtab, start_line, end_line); + } + } + else { + /* If we couldn't open the file, or got some prior error, just exit. */ + + return; + } + +} + +static CORE_ADDR +gdbtk_load_asm (clientData, pc, di) + ClientData clientData; + CORE_ADDR pc; + struct disassemble_info *di; +{ + struct disassembly_client_data * client_data + = (struct disassembly_client_data *) clientData; + char **text_argv; + int i, pc_to_line_len, line_to_pc_len; + gdbtk_result new_result, *old_result_ptr; + + pc_to_line_len = Tcl_DStringLength (&client_data->pc_to_line_prefix); + line_to_pc_len = Tcl_DStringLength (&client_data->line_to_pc_prefix); + + text_argv = client_data->asm_argv; + + /* Preserve the current Tcl result object, print out what we need, and then + suck it out of the result, and replace... */ + + old_result_ptr = result_ptr; + result_ptr = &new_result; + result_ptr->obj_ptr = client_data->result_obj[0]; + result_ptr->flags = GDBTK_TO_RESULT; + + /* Null out the three return objects we will use. */ + + for (i = 0; i < 3; i++) + Tcl_SetObjLength (client_data->result_obj[i], 0); + + print_address_numeric (pc, 1, gdb_stdout); + gdb_flush (gdb_stdout); + + result_ptr->obj_ptr = client_data->result_obj[1]; + + print_address_symbolic (pc, gdb_stdout, 1, "\t"); + gdb_flush (gdb_stdout); + + result_ptr->obj_ptr = client_data->result_obj[2]; + pc += (*tm_print_insn) (pc, di); + gdb_flush (gdb_stdout); + + client_data->widget_line_no++; + + text_argv[5] = Tcl_GetStringFromObj (client_data->result_obj[0], NULL); + text_argv[7] = Tcl_GetStringFromObj (client_data->result_obj[1], NULL); + text_argv[11] = Tcl_GetStringFromObj (client_data->result_obj[2], NULL); + + client_data->cmd.proc (client_data->cmd.clientData, + client_data->interp, 14, text_argv); + + if (*client_data->map_arr != '\0') + { + char buffer[16]; + + /* Run the command, then add an entry to the map array in + the caller's scope. */ + + Tcl_DStringAppend (&client_data->pc_to_line_prefix, text_argv[5], -1); + + /* FIXME: Convert to Tcl_SetVar2Ex when we move to 8.2. This + will allow us avoid converting widget_line_no into a string. */ + + sprintf (buffer, "%d", client_data->widget_line_no); + + Tcl_SetVar2 (client_data->interp, client_data->map_arr, + Tcl_DStringValue (&client_data->pc_to_line_prefix), + buffer, 0); + + Tcl_DStringAppend (&client_data->line_to_pc_prefix, buffer, -1); + + Tcl_SetVar2 (client_data->interp, client_data->map_arr, + Tcl_DStringValue (&client_data->line_to_pc_prefix), + text_argv[5], 0); + + /* Restore the prefixes to their initial state. */ + + Tcl_DStringSetLength (&client_data->pc_to_line_prefix, pc_to_line_len); + Tcl_DStringSetLength (&client_data->line_to_pc_prefix, line_to_pc_len); + + } + + result_ptr = old_result_ptr; + + return pc; +} + +static void +gdbtk_print_source (clientData, symtab, start_line, end_line) + ClientData clientData; + struct symtab *symtab; + int start_line; + int end_line; +{ + print_source_lines (symtab, start_line, end_line, 0); + gdb_flush (gdb_stdout); +} + +static CORE_ADDR +gdbtk_print_asm (clientData, pc, di) + ClientData clientData; + CORE_ADDR pc; + struct disassemble_info *di; +{ + fputs_unfiltered (" ", gdb_stdout); + print_address (pc, gdb_stdout); + fputs_unfiltered (":\t ", gdb_stdout); + pc += (*tm_print_insn) (pc, di); + fputs_unfiltered ("\n", gdb_stdout); + gdb_flush (gdb_stdout); + return pc; +} + +static int +gdb_disassemble_driver (low, high, mixed_source_and_assembly, + clientData, print_source_fn, print_asm_fn) + CORE_ADDR low; + CORE_ADDR high; + int mixed_source_and_assembly; + ClientData clientData; + void (*print_source_fn) (ClientData, struct symtab *, int, int); + CORE_ADDR (*print_asm_fn) (ClientData, CORE_ADDR, + struct disassemble_info *); +{ + CORE_ADDR pc; + static disassemble_info di; + static int di_initialized; + + if (! di_initialized) + { + INIT_DISASSEMBLE_INFO_NO_ARCH (di, gdb_stdout, + (fprintf_ftype) fprintf_unfiltered); + di.flavour = bfd_target_unknown_flavour; + di.memory_error_func = dis_asm_memory_error; + di.print_address_func = dis_asm_print_address; + di_initialized = 1; + } + + di.mach = TARGET_PRINT_INSN_INFO->mach; + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + di.endian = BFD_ENDIAN_BIG; + else + di.endian = BFD_ENDIAN_LITTLE; + + /* Set the architecture for multi-arch configurations. */ + if (TARGET_ARCHITECTURE != NULL) + di.mach = TARGET_ARCHITECTURE->mach; + + /* If disassemble_from_exec == -1, then we use the following heuristic to + determine whether or not to do disassembly from target memory or from the + exec file: + + If we're debugging a local process, read target memory, instead of the + exec file. This makes disassembly of functions in shared libs work + correctly. Also, read target memory if we are debugging native threads. + + Else, we're debugging a remote process, and should disassemble from the + exec file for speed. However, this is no good if the target modifies its + code (for relocation, or whatever). + */ + + if (disassemble_from_exec == -1) + { + if (strcmp (target_shortname, "child") == 0 + || strcmp (target_shortname, "procfs") == 0 + || strcmp (target_shortname, "vxprocess") == 0 + || strstr (target_shortname, "-threads") != NULL) + /* It's a child process, read inferior mem */ + disassemble_from_exec = 0; + else + /* It's remote, read the exec file */ + disassemble_from_exec = 1; + } + + if (disassemble_from_exec) + di.read_memory_func = gdbtk_dis_asm_read_memory; + else + di.read_memory_func = dis_asm_read_memory; + + /* If just doing straight assembly, all we need to do is disassemble + everything between low and high. If doing mixed source/assembly, we've + got a totally different path to follow. */ + + if (mixed_source_and_assembly) + { /* Come here for mixed source/assembly */ + /* The idea here is to present a source-O-centric view of a function to + the user. This means that things are presented in source order, with + (possibly) out of order assembly immediately following. */ + struct symtab *symtab; + struct linetable_entry *le; + int nlines; + int newlines; + struct my_line_entry *mle; + struct symtab_and_line sal; + int i; + int out_of_order; + int next_line; + + /* Assume symtab is valid for whole PC range */ + symtab = find_pc_symtab (low); + + if (!symtab || !symtab->linetable) + goto assembly_only; + + /* First, convert the linetable to a bunch of my_line_entry's. */ + + le = symtab->linetable->item; + nlines = symtab->linetable->nitems; + + if (nlines <= 0) + goto assembly_only; + + mle = (struct my_line_entry *) alloca (nlines * + sizeof (struct my_line_entry)); + + out_of_order = 0; + + /* Copy linetable entries for this function into our data structure, + creating end_pc's and setting out_of_order as appropriate. */ + + /* First, skip all the preceding functions. */ + + for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ; + + /* Now, copy all entries before the end of this function. */ + + newlines = 0; + for (; i < nlines - 1 && le[i].pc < high; i++) + { + if (le[i].line == le[i + 1].line + && le[i].pc == le[i + 1].pc) + continue; /* Ignore duplicates */ + + /* GCC sometimes emits line directives with a linenumber + of 0. It does this to handle live range splitting. + This may be a bug, but we need to be able to handle it. + For now, use the previous instructions line number. + Since this is a bit of a hack anyway, we will just lose + if the bogus sline is the first line of the range. For + functions, I have never seen this to be the case. */ + + if (le[i].line != 0) + { + mle[newlines].line = le[i].line; + } + else + { + if (newlines > 0) + mle[newlines].line = mle[newlines - 1].line; + } + + if (le[i].line > le[i + 1].line) + out_of_order = 1; + mle[newlines].start_pc = le[i].pc; + mle[newlines].end_pc = le[i + 1].pc; + newlines++; + } + + /* If we're on the last line, and it's part of the function, then we + need to get the end pc in a special way. */ + + if (i == nlines - 1 + && le[i].pc < high) + { + mle[newlines].line = le[i].line; + mle[newlines].start_pc = le[i].pc; + sal = find_pc_line (le[i].pc, 0); + mle[newlines].end_pc = sal.end; + newlines++; + } + + /* Now, sort mle by line #s (and, then by addresses within lines). */ + + if (out_of_order) + qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines); + + /* Now, for each line entry, emit the specified lines (unless they have + been emitted before), followed by the assembly code for that line. */ + + next_line = 0; /* Force out first line */ + for (i = 0; i < newlines; i++) + { + /* Print out everything from next_line to the current line. */ + + if (mle[i].line >= next_line) + { + if (next_line != 0) + print_source_fn (clientData, symtab, next_line, + mle[i].line + 1); + else + print_source_fn (clientData, symtab, mle[i].line, + mle[i].line + 1); + + next_line = mle[i].line + 1; + } + + for (pc = mle[i].start_pc; pc < mle[i].end_pc; ) + { + QUIT; + pc = print_asm_fn (clientData, pc, &di); + } + } + } + else + { + assembly_only: + for (pc = low; pc < high; ) + { + QUIT; + pc = print_asm_fn (clientData, pc, &di); + } + } + + return TCL_OK; +} + +/* This is the memory_read_func for gdb_disassemble when we are + disassembling from the exec file. */ + +static int +gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info) + bfd_vma memaddr; + bfd_byte *myaddr; + int len; + disassemble_info *info; +{ + extern struct target_ops exec_ops; + int res; + + errno = 0; + res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops); + + if (res == len) + return 0; + else if (errno == 0) + return EIO; + else + return errno; +} + +/* This will be passed to qsort to sort the results of the disassembly */ + +static int +compare_lines (mle1p, mle2p) + const PTR mle1p; + const PTR mle2p; +{ + struct my_line_entry *mle1, *mle2; + int val; + + mle1 = (struct my_line_entry *) mle1p; + mle2 = (struct my_line_entry *) mle2p; + + val = mle1->line - mle2->line; + + if (val != 0) + return val; + + return mle1->start_pc - mle2->start_pc; +} + +/* This implements the TCL command `gdb_loc', + + * Arguments: + * ?symbol? The symbol or address to locate - defaults to pc + * Tcl Return: + * a list consisting of the following: + * basename, function name, filename, line number, address, current pc + */ + +static int +gdb_loc (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char *filename; + struct symtab_and_line sal; + struct symbol *sym; + char *fname; + CORE_ADDR pc; + + if (objc == 1) + { + if (selected_frame && (selected_frame->pc != read_pc ())) + { + /* Note - this next line is not correct on all architectures. + For a graphical debugger we really want to highlight the + assembly line that called the next function on the stack. + Many architectures have the next instruction saved as the + pc on the stack, so what happens is the next instruction + is highlighted. FIXME */ + pc = selected_frame->pc; + sal = find_pc_line (selected_frame->pc, + selected_frame->next != NULL + && !selected_frame->next->signal_handler_caller + && !frame_in_dummy (selected_frame->next)); + } + else + { + pc = read_pc (); + sal = find_pc_line (pc, 0); + } + } + else if (objc == 2) + { + struct symtabs_and_lines sals; + int nelts; + + sals = decode_line_spec (Tcl_GetStringFromObj (objv[1], NULL), 1); + + nelts = sals.nelts; + sal = sals.sals[0]; + free (sals.sals); + + if (sals.nelts != 1) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Ambiguous line spec", -1); + return TCL_ERROR; + } + resolve_sal_pc (&sal); + pc = sal.pc; + } + else + { + Tcl_SetStringObj (result_ptr->obj_ptr, "wrong # args", -1); + return TCL_ERROR; + } + + if (sal.symtab) + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (sal.symtab->filename, -1)); + else + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj ("", 0)); + + fname = pc_function_name (pc); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (fname, -1)); + + filename = symtab_to_filename (sal.symtab); + if (filename == NULL) + filename = ""; + + /* file name */ + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (filename, -1)); + /* line number */ + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (sal.line)); + /* PC in current frame */ + sprintf_append_element_to_obj (result_ptr->obj_ptr, "0x%s", paddr_nz (pc)); + /* Real PC */ + sprintf_append_element_to_obj (result_ptr->obj_ptr, "0x%s", + paddr_nz (stop_pc)); + + /* shared library */ +#ifdef PC_SOLIB + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (PC_SOLIB (pc), -1)); +#else + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj ("", -1)); +#endif + return TCL_OK; +} + +/* This implements the Tcl command 'gdb_get_mem', which + * dumps a block of memory + * Arguments: + * gdb_get_mem addr form size nbytes bpr aschar + * + * addr: address of data to dump + * form: a char indicating format + * size: size of each element; 1,2,4, or 8 bytes + * nbytes: the number of bytes to read + * bpr: bytes per row + * aschar: if present, an ASCII dump of the row is included. ASCHAR + * used for unprintable characters. + * + * Return: + * a list of elements followed by an optional ASCII dump */ + +static int +gdb_get_mem (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int size, asize, i, j, bc; + CORE_ADDR addr; + int nbytes, rnum, bpr; + long tmp; + char format, buff[128], aschar, *mbuf, *mptr, *cptr, *bptr; + struct type *val_type; + + if (objc < 6 || objc > 7) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "addr format size bytes bytes_per_row ?ascii_char?", + -1); + return TCL_ERROR; + } + + if (Tcl_GetIntFromObj (interp, objv[3], &size) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + else if (size <= 0) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Invalid size, must be > 0", -1); + return TCL_ERROR; + } + + if (Tcl_GetIntFromObj (interp, objv[4], &nbytes) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + else if (nbytes <= 0) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "Invalid number of bytes, must be > 0", + -1); + return TCL_ERROR; + } + + if (Tcl_GetIntFromObj (interp, objv[5], &bpr) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + else if (bpr <= 0) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "Invalid bytes per row, must be > 0", -1); + return TCL_ERROR; + } + + if (Tcl_GetLongFromObj (interp, objv[1], &tmp) != TCL_OK) + return TCL_OK; + + addr = (CORE_ADDR) tmp; + + format = *(Tcl_GetStringFromObj (objv[2], NULL)); + mbuf = (char *) malloc (nbytes + 32); + if (!mbuf) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Out of memory.", -1); + return TCL_ERROR; + } + + memset (mbuf, 0, nbytes + 32); + mptr = cptr = mbuf; + + rnum = 0; + while (rnum < nbytes) + { + int error; + int num = target_read_memory_partial (addr + rnum, mbuf + rnum, + nbytes - rnum, &error); + if (num <= 0) + break; + rnum += num; + } + + if (objc == 7) + aschar = *(Tcl_GetStringFromObj (objv[6], NULL)); + else + aschar = 0; + + switch (size) + { + case 1: + val_type = builtin_type_int8; + asize = 'b'; + break; + case 2: + val_type = builtin_type_int16; + asize = 'h'; + break; + case 4: + val_type = builtin_type_int32; + asize = 'w'; + break; + case 8: + val_type = builtin_type_int64; + asize = 'g'; + break; + default: + val_type = builtin_type_int8; + asize = 'b'; + } + + bc = 0; /* count of bytes in a row */ + bptr = &buff[0]; /* pointer for ascii dump */ + + /* Build up the result as a list... */ + + result_ptr->flags |= GDBTK_MAKES_LIST; + + for (i = 0; i < nbytes; i += size) + { + if (i >= rnum) + { + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj ("N/A", 3)); + if (aschar) + for (j = 0; j < size; j++) + *bptr++ = 'X'; + } + else + { + print_scalar_formatted (mptr, val_type, format, asize, gdb_stdout); + + if (aschar) + { + for (j = 0; j < size; j++) + { + *bptr = *cptr++; + if (*bptr < 32 || *bptr > 126) + *bptr = aschar; + bptr++; + } + } + } + + mptr += size; + bc += size; + + if (aschar && (bc >= bpr)) + { + /* end of row. Add it to the result and reset variables */ + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (buff, bc)); + bc = 0; + bptr = &buff[0]; + } + } + + result_ptr->flags &= ~GDBTK_MAKES_LIST; + + free (mbuf); + return TCL_OK; +} + + +/* This implements the tcl command "gdb_loadfile" + * It loads a c source file into a text widget. + * + * Tcl Arguments: + * widget: the name of the text widget to fill + * filename: the name of the file to load + * linenumbers: A boolean indicating whether or not to display line numbers. + * Tcl Result: + * + */ + +/* In this routine, we will build up a "line table", i.e. a + * table of bits showing which lines in the source file are executible. + * LTABLE_SIZE is the number of bytes to allocate for the line table. + * + * Its size limits the maximum number of lines + * in a file to 8 * LTABLE_SIZE. This memory is freed after + * the file is loaded, so it is OK to make this very large. + * Additional memory will be allocated if needed. */ +#define LTABLE_SIZE 20000 +static int +gdb_loadfile (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char *file, *widget; + int linenumbers, ln, lnum, ltable_size; + FILE *fp; + char *ltable; + struct symtab *symtab; + struct linetable_entry *le; + long mtime = 0; + struct stat st; + char line[10000], line_num_buf[18]; + int prefix_len_1, prefix_len_2, cur_prefix_len, widget_len; + char *text_argv[8]; + Tcl_CmdInfo text_cmd; + + + if (objc != 4) + { + Tcl_WrongNumArgs(interp, 1, objv, "widget filename linenumbers"); + return TCL_ERROR; + } + + widget = Tcl_GetStringFromObj (objv[1], NULL); + if ( Tk_NameToWindow (interp, widget, Tk_MainWindow (interp)) == NULL) + { + return TCL_ERROR; + } + + if (!Tcl_GetCommandInfo (interp, widget, &text_cmd)) + { + Tcl_SetStringObj (result_ptr->obj_ptr, "Can't get widget command info", + -1); + return TCL_ERROR; + } + + file = Tcl_GetStringFromObj (objv[2], NULL); + Tcl_GetBooleanFromObj (interp, objv[3], &linenumbers); + + symtab = full_lookup_symtab (file); + if (!symtab) + { + Tcl_SetStringObj ( result_ptr->obj_ptr, "File not found in symtab", -1); + return TCL_ERROR; + } + + file = symtab_to_filename ( symtab ); + if ((fp = fopen ( file, "r" )) == NULL) + { + Tcl_SetStringObj ( result_ptr->obj_ptr, "Can't open file for reading", + -1); + return TCL_ERROR; + } + + if (stat (file, &st) < 0) + { + catch_errors (perror_with_name_wrapper, "gdbtk: get time stamp", "", + RETURN_MASK_ALL); + return TCL_ERROR; + } + + if (symtab && symtab->objfile && symtab->objfile->obfd) + mtime = bfd_get_mtime(symtab->objfile->obfd); + else if (exec_bfd) + mtime = bfd_get_mtime(exec_bfd); + + if (mtime && mtime < st.st_mtime) + { + gdbtk_ignorable_warning("file_times",\ + "Source file is more recent than executable.\n"); + } + + + /* Source linenumbers don't appear to be in order, and a sort is */ + /* too slow so the fastest solution is just to allocate a huge */ + /* array and set the array entry for each linenumber */ + + ltable_size = LTABLE_SIZE; + ltable = (char *)malloc (LTABLE_SIZE); + if (ltable == NULL) + { + Tcl_SetStringObj ( result_ptr->obj_ptr, "Out of memory.", -1); + fclose (fp); + return TCL_ERROR; + } + + memset (ltable, 0, LTABLE_SIZE); + + if (symtab->linetable && symtab->linetable->nitems) + { + le = symtab->linetable->item; + for (ln = symtab->linetable->nitems ;ln > 0; ln--, le++) + { + lnum = le->line >> 3; + if (lnum >= ltable_size) + { + char *new_ltable; + new_ltable = (char *)realloc (ltable, ltable_size*2); + memset (new_ltable + ltable_size, 0, ltable_size); + ltable_size *= 2; + if (new_ltable == NULL) + { + Tcl_SetStringObj ( result_ptr->obj_ptr, "Out of memory.", + -1); + free (ltable); + fclose (fp); + return TCL_ERROR; + } + ltable = new_ltable; + } + ltable[lnum] |= 1 << (le->line % 8); + } + } + + ln = 1; + + line[0] = '\t'; + text_argv[0] = widget; + text_argv[1] = "insert"; + text_argv[2] = "end"; + text_argv[5] = line; + text_argv[6] = "source_tag"; + text_argv[8] = NULL; + + if (linenumbers) + { + int found_carriage_return = 1; + + line_num_buf[1] = '\t'; + + text_argv[3] = line_num_buf; + + while (fgets (line + 1, 9980, fp)) + { + char *p; + + /* Look for DOS style \r\n endings, and if found, + * strip off the \r. We assume (for the sake of + * speed) that ALL lines in the file have DOS endings, + * or none do. + */ + + if (found_carriage_return) { + char *p; + + p = strrchr(line, '\0') - 2; + if (*p == '\r') { + *p = '\n'; + *(p + 1) = '\0'; + } else { + found_carriage_return = 0; + } + } + + sprintf (line_num_buf+2, "%d", ln); + if (ltable[ln >> 3] & (1 << (ln % 8))) + { + line_num_buf[0] = '-'; + text_argv[4] = "break_rgn_tag"; + } + else + { + line_num_buf[0] = ' '; + text_argv[4] = ""; + } + + text_cmd.proc(text_cmd.clientData, interp, 7, text_argv); + ln++; + } + } + else + { + int found_carriage_return = 1; + + while (fgets (line + 1, 9980, fp)) + { + if (found_carriage_return) { + char *p; + + p = strrchr(line, '\0') - 2; + if (*p == '\r') { + *p = '\n'; + *(p + 1) = '\0'; + } else { + found_carriage_return = 0; + } + } + + if (ltable[ln >> 3] & (1 << (ln % 8))) + { + text_argv[3] = "- "; + text_argv[4] = "break_rgn_tag"; + } + else + { + text_argv[3] = " "; + text_argv[4] = ""; + } + + text_cmd.proc(text_cmd.clientData, interp, 7, text_argv); + ln++; + } + } + + free (ltable); + fclose (fp); + return TCL_OK; +} + +/* + * This section contains commands for manipulation of breakpoints. + */ + + +/* set a breakpoint by source file and line number */ +/* flags are as follows: */ +/* least significant 2 bits are disposition, rest is */ +/* type (normally 0). + + enum bptype { + bp_breakpoint, Normal breakpoint + bp_hardware_breakpoint, Hardware assisted breakpoint + } + + Disposition of breakpoint. Ie: what to do after hitting it. + enum bpdisp { + del, Delete it + del_at_next_stop, Delete at next stop, whether hit or not + disable, Disable it + donttouch Leave it alone + }; + */ + +/* This implements the tcl command "gdb_set_bp" + * It sets breakpoints, and runs the Tcl command + * gdbtk_tcl_breakpoint create + * to register the new breakpoint with the GUI. + * + * Tcl Arguments: + * filename: the file in which to set the breakpoint + * line: the line number for the breakpoint + * type: the type of the breakpoint + * thread: optional thread number + * Tcl Result: + * The return value of the call to gdbtk_tcl_breakpoint. + */ + +static int +gdb_set_bp (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symtab_and_line sal; + int line, ret, thread = -1; + struct breakpoint *b; + char buf[64], *typestr; + Tcl_DString cmd; + enum bpdisp disp; + + if (objc != 4 && objc != 5) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "wrong number of args, should be \"filename line type [thread]\"", -1); + return TCL_ERROR; + } + + sal.symtab = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL)); + if (sal.symtab == NULL) + return TCL_ERROR; + + if (Tcl_GetIntFromObj (interp, objv[2], &line) == TCL_ERROR) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + typestr = Tcl_GetStringFromObj (objv[3], NULL); + if (typestr == NULL) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + if (strncmp (typestr, "temp", 4) == 0) + disp = del; + else if (strncmp (typestr, "normal", 6) == 0) + disp = donttouch; + else + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "type must be \"temp\" or \"normal\"", -1); + return TCL_ERROR; + } + + if (objc == 5) + { + if (Tcl_GetIntFromObj (interp, objv[4], &thread) == TCL_ERROR) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + } + + sal.line = line; + if (!find_line_pc (sal.symtab, sal.line, &sal.pc)) + return TCL_ERROR; + + sal.section = find_pc_overlay (sal.pc); + b = set_raw_breakpoint (sal); + set_breakpoint_count (breakpoint_count + 1); + b->number = breakpoint_count; + b->type = bp_breakpoint; + b->disposition = disp; + b->thread = thread; + + /* FIXME: this won't work for duplicate basenames! */ + sprintf (buf, "%s:%d", basename (Tcl_GetStringFromObj (objv[1], NULL)), + line); + b->addr_string = strsave (buf); + + /* now send notification command back to GUI */ + + Tcl_DStringInit (&cmd); + + Tcl_DStringAppend (&cmd, "gdbtk_tcl_breakpoint create ", -1); + sprintf (buf, "%d", b->number); + Tcl_DStringAppendElement (&cmd, buf); + sprintf (buf, "0x%lx", (long) sal.pc); + Tcl_DStringAppendElement (&cmd, buf); + Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[2], NULL)); + Tcl_DStringAppendElement (&cmd, Tcl_GetStringFromObj (objv[1], NULL)); + Tcl_DStringAppendElement (&cmd, bpdisp[b->disposition]); + sprintf (buf, "%d", b->enable); + Tcl_DStringAppendElement (&cmd, buf); + sprintf (buf, "%d", b->thread); + Tcl_DStringAppendElement (&cmd, buf); + + + ret = Tcl_Eval (interp, Tcl_DStringValue (&cmd)); + Tcl_DStringFree (&cmd); + return ret; +} + +/* This implements the tcl command "gdb_set_bp_addr" + * It sets breakpoints, and runs the Tcl command + * gdbtk_tcl_breakpoint create + * to register the new breakpoint with the GUI. + * + * Tcl Arguments: + * addr: the address at which to set the breakpoint + * type: the type of the breakpoint + * thread: optional thread number + * Tcl Result: + * The return value of the call to gdbtk_tcl_breakpoint. + */ + +static int +gdb_set_bp_addr (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + +{ + struct symtab_and_line sal; + int line, ret, thread = -1; + long addr; + struct breakpoint *b; + char *filename, *typestr, buf[64]; + Tcl_DString cmd; + enum bpdisp disp; + + if (objc != 4 && objc != 3) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "wrong number of args, should be \"address type [thread]\"", -1); + return TCL_ERROR; + } + + if (Tcl_GetLongFromObj (interp, objv[1], &addr) == TCL_ERROR) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + typestr = Tcl_GetStringFromObj (objv[2], NULL); + if (typestr == NULL) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + if (strncmp (typestr, "temp", 4) == 0) + disp = del; + else if (strncmp (typestr, "normal", 6) == 0) + disp = donttouch; + else + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "type must be \"temp\" or \"normal\"", -1); + return TCL_ERROR; + } + + if (objc == 4) + { + if (Tcl_GetIntFromObj (interp, objv[3], &thread) == TCL_ERROR) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + } + + sal = find_pc_line (addr, 0); + sal.pc = addr; + b = set_raw_breakpoint (sal); + set_breakpoint_count (breakpoint_count + 1); + b->number = breakpoint_count; + b->type = bp_breakpoint; + b->disposition = disp; + b->thread = thread; + + sprintf (buf, "*(0x%lx)", addr); + b->addr_string = strsave (buf); + + /* now send notification command back to GUI */ + + Tcl_DStringInit (&cmd); + + Tcl_DStringAppend (&cmd, "gdbtk_tcl_breakpoint create ", -1); + sprintf (buf, "%d", b->number); + Tcl_DStringAppendElement (&cmd, buf); + sprintf (buf, "0x%lx", addr); + Tcl_DStringAppendElement (&cmd, buf); + sprintf (buf, "%d", b->line_number); + Tcl_DStringAppendElement (&cmd, buf); + + filename = symtab_to_filename (sal.symtab); + if (filename == NULL) + filename = ""; + Tcl_DStringAppendElement (&cmd, filename); + Tcl_DStringAppendElement (&cmd, bpdisp[b->disposition]); + sprintf (buf, "%d", b->enable); + Tcl_DStringAppendElement (&cmd, buf); + sprintf (buf, "%d", b->thread); + Tcl_DStringAppendElement (&cmd, buf); + + ret = Tcl_Eval (interp, Tcl_DStringValue (&cmd)); + Tcl_DStringFree (&cmd); + return ret; +} + +/* This implements the tcl command "gdb_find_bp_at_line" + + * Tcl Arguments: + * filename: the file in which to find the breakpoint + * line: the line number for the breakpoint + * Tcl Result: + * It returns a list of breakpoint numbers + */ + +static int +gdb_find_bp_at_line (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + +{ + struct symtab *s; + int line; + struct breakpoint *b; + extern struct breakpoint *breakpoint_chain; + + if (objc != 3) + { + Tcl_WrongNumArgs (interp, 1, objv, "filename line"); + return TCL_ERROR; + } + + s = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL)); + if (s == NULL) + return TCL_ERROR; + + if (Tcl_GetIntFromObj (interp, objv[2], &line) == TCL_ERROR) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + for (b = breakpoint_chain; b; b = b->next) + if (b->line_number == line && !strcmp (b->source_file, s->filename)) + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (b->number)); + + return TCL_OK; +} + + +/* This implements the tcl command "gdb_find_bp_at_addr" + + * Tcl Arguments: + * addr: address + * Tcl Result: + * It returns a list of breakpoint numbers + */ + +static int +gdb_find_bp_at_addr (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + +{ + long addr; + struct breakpoint *b; + extern struct breakpoint *breakpoint_chain; + + if (objc != 2) + { + Tcl_WrongNumArgs (interp, 1, objv, "address"); + return TCL_ERROR; + } + + if (Tcl_GetLongFromObj (interp, objv[1], &addr) == TCL_ERROR) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + for (b = breakpoint_chain; b; b = b->next) + if (b->address == (CORE_ADDR) addr) + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (b->number)); + + return TCL_OK; +} + +/* This implements the tcl command gdb_get_breakpoint_info + + + * Tcl Arguments: + * breakpoint_number + * Tcl Result: + * A list with {file, function, line_number, address, type, enabled?, + * disposition, ignore_count, {list_of_commands}, + * thread, hit_count} + */ + +static int +gdb_get_breakpoint_info (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct symtab_and_line sal; + struct command_line *cmd; + int bpnum; + struct breakpoint *b; + extern struct breakpoint *breakpoint_chain; + char *funcname, *filename; + struct symbol *sym; + Tcl_Obj *new_obj; + + if (objc != 2) + { + Tcl_SetStringObj (result_ptr->obj_ptr, + "wrong number of args, should be \"breakpoint\"", -1); + return TCL_ERROR; + } + + if (Tcl_GetIntFromObj (NULL, objv[1], &bpnum) != TCL_OK) + { + result_ptr->flags = GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + for (b = breakpoint_chain; b; b = b->next) + if (b->number == bpnum) + break; + + if (!b || b->type != bp_breakpoint) + { + char err_buf[64]; + sprintf (err_buf, "Breakpoint #%d does not exist.", bpnum); + Tcl_SetStringObj (result_ptr->obj_ptr, err_buf, -1); + return TCL_ERROR; + } + + sal = find_pc_line (b->address, 0); + + filename = symtab_to_filename (sal.symtab); + if (filename == NULL) + filename = ""; + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (filename, -1)); + + funcname = pc_function_name (b->address); + new_obj = Tcl_NewStringObj (funcname, -1); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, new_obj); + + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (b->line_number)); + sprintf_append_element_to_obj (result_ptr->obj_ptr, "0x%s", + paddr_nz (b->address)); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (bptypes[b->type], -1)); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewBooleanObj (b->enable == enabled)); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (bpdisp[b->disposition], -1)); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (b->ignore_count)); + + new_obj = Tcl_NewObj (); + for (cmd = b->commands; cmd; cmd = cmd->next) + Tcl_ListObjAppendElement (NULL, new_obj, + Tcl_NewStringObj (cmd->line, -1)); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, new_obj); + + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj (b->cond_string, -1)); + + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (b->thread)); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (b->hit_count)); + + return TCL_OK; +} + + +/* This implements the tcl command gdb_get_breakpoint_list + * It builds up a list of the current breakpoints. + * + * Tcl Arguments: + * None. + * Tcl Result: + * A list of breakpoint numbers. + */ + +static int +gdb_get_breakpoint_list (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct breakpoint *b; + extern struct breakpoint *breakpoint_chain; + Tcl_Obj *new_obj; + + if (objc != 1) + error ("wrong number of args, none are allowed"); + + for (b = breakpoint_chain; b; b = b->next) + if (b->type == bp_breakpoint) + { + new_obj = Tcl_NewIntObj (b->number); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, new_obj); + } + + return TCL_OK; +} + +/* The functions in this section deal with stacks and backtraces. */ + +/* This implements the tcl command gdb_stack. + * It builds up a list of stack frames. + * + * Tcl Arguments: + * start - starting stack frame + * count - number of frames to inspect + * Tcl Result: + * A list of function names + */ + +static int +gdb_stack (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + int start, count; + + if (objc < 3) + { + Tcl_WrongNumArgs (interp, 1, objv, "start count"); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + if (Tcl_GetIntFromObj (NULL, objv[1], &start)) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + if (Tcl_GetIntFromObj (NULL, objv[2], &count)) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + if (target_has_stack) + { + struct frame_info *top; + struct frame_info *fi; + + /* Find the outermost frame */ + fi = get_current_frame (); + while (fi != NULL) + { + top = fi; + fi = get_prev_frame (fi); + } + + /* top now points to the top (outermost frame) of the + stack, so point it to the requested start */ + start = -start; + top = find_relative_frame (top, &start); + + /* If start != 0, then we have asked to start outputting + frames beyond the innermost stack frame */ + if (start == 0) + { + fi = top; + while (fi && count--) + { + get_frame_name (interp, result_ptr->obj_ptr, fi); + fi = get_next_frame (fi); + } + } + } + + return TCL_OK; +} + +/* A helper function for get_stack which adds information about + * the stack frame FI to the caller's LIST. + * + * This is stolen from print_frame_info in stack.c. + */ +static void +get_frame_name (interp, list, fi) + Tcl_Interp *interp; + Tcl_Obj *list; + struct frame_info *fi; +{ + struct symtab_and_line sal; + struct symbol *func = NULL; + register char *funname = 0; + enum language funlang = language_unknown; + Tcl_Obj *objv[1]; + + if (frame_in_dummy (fi)) + { + objv[0] = Tcl_NewStringObj ("<function called from gdb>\n", -1); + Tcl_ListObjAppendElement (interp, list, objv[0]); + return; + } + if (fi->signal_handler_caller) + { + objv[0] = Tcl_NewStringObj ("<signal handler called>\n", -1); + Tcl_ListObjAppendElement (interp, list, objv[0]); + return; + } + + sal = + find_pc_line (fi->pc, + fi->next != NULL + && !fi->next->signal_handler_caller + && !frame_in_dummy (fi->next)); + + func = find_pc_function (fi->pc); + if (func) + { + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); + if (msymbol != NULL + && (SYMBOL_VALUE_ADDRESS (msymbol) + > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) + { + func = 0; + funname = GDBTK_SYMBOL_SOURCE_NAME (msymbol); + funlang = SYMBOL_LANGUAGE (msymbol); + } + else + { + funname = GDBTK_SYMBOL_SOURCE_NAME (func); + funlang = SYMBOL_LANGUAGE (func); + } + } + else + { + struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); + if (msymbol != NULL) + { + funname = GDBTK_SYMBOL_SOURCE_NAME (msymbol); + funlang = SYMBOL_LANGUAGE (msymbol); + } + } + + if (sal.symtab) + { + char *name = NULL; + + objv[0] = Tcl_NewStringObj (funname, -1); + Tcl_ListObjAppendElement (interp, list, objv[0]); + } + else + { +#if 0 + /* we have no convenient way to deal with this yet... */ + if (fi->pc != sal.pc || !sal.symtab) + { + print_address_numeric (fi->pc, 1, gdb_stdout); + printf_filtered (" in "); + } + printf_symbol_filtered (gdb_stdout, funname ? funname : "??", funlang, + DMGL_ANSI); +#endif + objv[0] = Tcl_NewStringObj (funname != NULL ? funname : "??", -1); +#ifdef PC_LOAD_SEGMENT + /* If we couldn't print out function name but if can figure out what + load segment this pc value is from, at least print out some info + about its load segment. */ + if (!funname) + { + Tcl_AppendStringsToObj (objv[0], " from ", PC_LOAD_SEGMENT (fi->pc), + (char *) NULL); + } +#endif +#ifdef PC_SOLIB + if (!funname) + { + char *lib = PC_SOLIB (fi->pc); + if (lib) + { + Tcl_AppendStringsToObj (objv[0], " from ", lib, (char *) NULL); + } + } +#endif + Tcl_ListObjAppendElement (interp, list, objv[0]); + } +} + +/* This implements the tcl command gdb_selected_frame + + * Returns the address of the selected frame + * frame. + * + * Arguments: + * None + * Tcl Result: + * The currently selected frame's address + */ + +static int +gdb_selected_frame (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char frame[32]; + + if (selected_frame == NULL) + strcpy (frame, ""); + else + sprintf (frame, "0x%s", paddr_nz (FRAME_FP (selected_frame))); + + Tcl_SetStringObj (result_ptr->obj_ptr, frame, -1); + + return TCL_OK; +} + +/* This implements the tcl command gdb_selected_block + * + * Returns the start and end addresses of the innermost + * block in the selected frame. + * + * Arguments: + * None + * Tcl Result: + * The currently selected block's start and end addresses + */ + +static int +gdb_selected_block (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + char start[32]; + char end[32]; + + if (selected_frame == NULL) + { + strcpy (start, ""); + strcpy (end, ""); + } + else + { + struct block *block; + block = get_frame_block (selected_frame); + sprintf (start, "0x%s", paddr_nz (BLOCK_START (block))); + sprintf (end, "0x%s", paddr_nz (BLOCK_END (block))); + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (start, -1)); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (end, -1)); + + return TCL_OK; +} + +/* This implements the tcl command gdb_get_blocks + * + * Returns the start and end addresses for all blocks in + * the selected frame. + * + * Arguments: + * None + * Tcl Result: + * A list of all valid blocks in the selected_frame. + */ + +static int +gdb_get_blocks (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct block *block; + int nsyms, i, junk; + struct symbol *sym; + CORE_ADDR pc; + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + + if (selected_frame != NULL) + { + block = get_frame_block (selected_frame); + pc = get_frame_pc (selected_frame); + while (block != 0) + { + nsyms = BLOCK_NSYMS (block); + junk = 0; + for (i = 0; i < nsyms; i++) + { + sym = BLOCK_SYM (block, i); + switch (SYMBOL_CLASS (sym)) + { + default: + case LOC_UNDEF: /* catches errors */ + case LOC_CONST: /* constant */ + case LOC_TYPEDEF: /* local typedef */ + case LOC_LABEL: /* local label */ + case LOC_BLOCK: /* local function */ + case LOC_CONST_BYTES: /* loc. byte seq. */ + case LOC_UNRESOLVED: /* unresolved static */ + case LOC_OPTIMIZED_OUT: /* optimized out */ + junk = 1; + break; + + case LOC_ARG: /* argument */ + case LOC_REF_ARG: /* reference arg */ + case LOC_REGPARM: /* register arg */ + case LOC_REGPARM_ADDR: /* indirect register arg */ + case LOC_LOCAL_ARG: /* stack arg */ + case LOC_BASEREG_ARG: /* basereg arg */ + + case LOC_LOCAL: /* stack local */ + case LOC_BASEREG: /* basereg local */ + case LOC_STATIC: /* static */ + case LOC_REGISTER: /* register */ + junk = 0; + break; + } + } + + /* If we found a block with locals in it, add it to the list. + Note that the ranges of start and end address for blocks + are exclusive, so double-check against the PC */ + + if (!junk && pc < BLOCK_END (block)) + { + char addr[32]; + + Tcl_Obj *elt = Tcl_NewListObj (0, NULL); + sprintf (addr, "0x%s", paddr_nz (BLOCK_START (block))); + Tcl_ListObjAppendElement (interp, elt, + Tcl_NewStringObj (addr, -1)); + sprintf (addr, "0x%s", paddr_nz (BLOCK_END (block))); + Tcl_ListObjAppendElement (interp, elt, + Tcl_NewStringObj (addr, -1)); + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, elt); + } + + if (BLOCK_FUNCTION (block)) + break; + else + block = BLOCK_SUPERBLOCK (block); + } + } + + return TCL_OK; +} + +/* This implements the tcl command gdb_block_vars. + * + * Returns all variables valid in the specified block. + * + * Arguments: + * The start and end addresses which identify the block. + * Tcl Result: + * All variables defined in the given block. + */ + +static int +gdb_block_vars (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + struct block *block; + int nsyms, i; + struct symbol *sym; + CORE_ADDR start, end; + + if (objc < 3) + { + Tcl_WrongNumArgs (interp, 1, objv, "startAddr endAddr"); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); + if (selected_frame == NULL) + return TCL_OK; + + start = parse_and_eval_address (Tcl_GetStringFromObj (objv[1], NULL)); + end = parse_and_eval_address (Tcl_GetStringFromObj (objv[2], NULL)); + + block = get_frame_block (selected_frame); + + while (block != 0) + { + if (BLOCK_START (block) == start && BLOCK_END (block) == end) + { + nsyms = BLOCK_NSYMS (block); + for (i = 0; i < nsyms; i++) + { + sym = BLOCK_SYM (block, i); + switch (SYMBOL_CLASS (sym)) + { + case LOC_ARG: /* argument */ + case LOC_REF_ARG: /* reference arg */ + case LOC_REGPARM: /* register arg */ + case LOC_REGPARM_ADDR: /* indirect register arg */ + case LOC_LOCAL_ARG: /* stack arg */ + case LOC_BASEREG_ARG: /* basereg arg */ + case LOC_LOCAL: /* stack local */ + case LOC_BASEREG: /* basereg local */ + case LOC_STATIC: /* static */ + case LOC_REGISTER: /* register */ + Tcl_ListObjAppendElement (interp, result_ptr->obj_ptr, + Tcl_NewStringObj (SYMBOL_NAME (sym), + -1)); + break; + + default: + break; + } + } + + return TCL_OK; + } + else if (BLOCK_FUNCTION (block)) + break; + else + block = BLOCK_SUPERBLOCK (block); + } + + return TCL_OK; +} + +/* + * This section contains a bunch of miscellaneous utility commands + */ + +/* This implements the tcl command gdb_path_conv + + * On Windows, it canonicalizes the pathname, + * On Unix, it is a no op. + * + * Arguments: + * path + * Tcl Result: + * The canonicalized path. + */ + +static int +gdb_path_conv (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + if (objc != 2) + error ("wrong # args"); + +#ifdef __CYGWIN__ + { + char pathname[256], *ptr; + + cygwin32_conv_to_full_win32_path (Tcl_GetStringFromObj (objv[1], NULL), + pathname); + for (ptr = pathname; *ptr; ptr++) + { + if (*ptr == '\\') + *ptr = '/'; + } + Tcl_SetStringObj (result_ptr->obj_ptr, pathname, -1); + } +#else + Tcl_SetStringObj (result_ptr->obj_ptr, Tcl_GetStringFromObj (objv[1], NULL), + -1); +#endif + + return TCL_OK; +} + +/* + * This section has utility routines that are not Tcl commands. + */ + +static int +perror_with_name_wrapper (args) + PTR args; +{ + perror_with_name (args); + return 1; +} + +/* The lookup_symtab() in symtab.c doesn't work correctly */ +/* It will not work will full pathnames and if multiple */ +/* source files have the same basename, it will return */ +/* the first one instead of the correct one. This version */ +/* also always makes sure symtab->fullname is set. */ + +static struct symtab * +full_lookup_symtab (file) + char *file; +{ + struct symtab *st; + struct objfile *objfile; + char *bfile, *fullname; + struct partial_symtab *pt; + + if (!file) + return NULL; + + /* first try a direct lookup */ + st = lookup_symtab (file); + if (st) + { + if (!st->fullname) + symtab_to_filename (st); + return st; + } + + /* if the direct approach failed, try */ + /* looking up the basename and checking */ + /* all matches with the fullname */ + bfile = basename (file); + ALL_SYMTABS (objfile, st) + { + if (!strcmp (bfile, basename (st->filename))) + { + if (!st->fullname) + fullname = symtab_to_filename (st); + else + fullname = st->fullname; + + if (!strcmp (file, fullname)) + return st; + } + } + + /* still no luck? look at psymtabs */ + ALL_PSYMTABS (objfile, pt) + { + if (!strcmp (bfile, basename (pt->filename))) + { + st = PSYMTAB_TO_SYMTAB (pt); + if (st) + { + fullname = symtab_to_filename (st); + if (!strcmp (file, fullname)) + return st; + } + } + } + return NULL; +} + +/* Look for the function that contains PC and return the source + (demangled) name for this function. + + If no symbol is found, it returns an empty string. In either + case, memory is owned by gdb. Do not attempt to free it. */ +char * +pc_function_name (pc) + CORE_ADDR pc; +{ + struct symbol *sym; + char *funcname = NULL; + + /* First lookup the address in the symbol table... */ + sym = find_pc_function (pc); + if (sym != NULL) + funcname = GDBTK_SYMBOL_SOURCE_NAME (sym); + else + { + /* ... if that fails, look it up in the minimal symbols. */ + struct minimal_symbol *msym = NULL; + + msym = lookup_minimal_symbol_by_pc (pc); + if (msym != NULL) + funcname = GDBTK_SYMBOL_SOURCE_NAME (msym); + } + + if (funcname == NULL) + funcname = ""; + + return funcname; +} + +static void +setup_architecture_data () +{ + /* don't trust REGISTER_BYTES to be zero. */ + old_regs = xmalloc (REGISTER_BYTES + 1); + memset (old_regs, 0, REGISTER_BYTES + 1); +} + + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/generic/gdbtk-hooks.c b/gdb/gdbtk/generic/gdbtk-hooks.c new file mode 100644 index 00000000000..3f0462bb181 --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk-hooks.c @@ -0,0 +1,902 @@ +/* Startup code for gdbtk. + Copyright 1994-1998, 2000 Free Software Foundation, Inc. + + Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "inferior.h" +#include "command.h" +#include "bfd.h" +#include "symfile.h" +#include "objfiles.h" +#include "target.h" +#include "gdbcore.h" +#include "tracepoint.h" +#include "demangle.h" + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + +#include <sys/stat.h> + +#include <tcl.h> +#include <tk.h> +#include <itcl.h> +#include <tix.h> +#include "guitcl.h" +#include "gdbtk.h" + +#include <stdarg.h> +#include <signal.h> +#include <fcntl.h> +#include "top.h" +#include <sys/ioctl.h> +#include "gdb_string.h" +#include "dis-asm.h" +#include <stdio.h> +#include "gdbcmd.h" + +#include "annotate.h" +#include <sys/time.h> + +volatile int in_fputs = 0; + +/* Set by gdb_stop, this flag informs x_event to tell its caller + that it should forcibly detach from the target. */ +int gdbtk_force_detach = 0; + +extern void (*pre_add_symbol_hook) PARAMS ((char *)); +extern void (*post_add_symbol_hook) PARAMS ((void)); +extern void (*selected_frame_level_changed_hook) PARAMS ((int)); +extern int (*ui_loop_hook) PARAMS ((int)); + +static void gdbtk_create_tracepoint PARAMS ((struct tracepoint *)); +static void gdbtk_delete_tracepoint PARAMS ((struct tracepoint *)); +static void gdbtk_modify_tracepoint PARAMS ((struct tracepoint *)); +static void gdbtk_trace_find PARAMS ((char *arg, int from_tty)); +static void gdbtk_trace_start_stop PARAMS ((int, int)); +static void gdbtk_create_breakpoint PARAMS ((struct breakpoint *)); +static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *)); +static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *)); +static void gdbtk_attach PARAMS ((void)); +static void gdbtk_detach PARAMS ((void)); +static void gdbtk_file_changed PARAMS ((char *)); +static void gdbtk_exec_file_display PARAMS ((char *)); +static void tk_command_loop PARAMS ((void)); +static void gdbtk_call_command PARAMS ((struct cmd_list_element *, char *, int)); +static int gdbtk_wait PARAMS ((int, struct target_waitstatus *)); +int x_event PARAMS ((int)); +static int gdbtk_query PARAMS ((const char *, va_list)); +static void gdbtk_warning PARAMS ((const char *, va_list)); +static char *gdbtk_readline PARAMS ((char *)); +static void gdbtk_readline_begin (char *format,...); +static void gdbtk_readline_end PARAMS ((void)); +static void gdbtk_pre_add_symbol PARAMS ((char *)); +static void gdbtk_print_frame_info PARAMS ((struct symtab *, int, int, int)); +static void gdbtk_post_add_symbol PARAMS ((void)); +static void gdbtk_register_changed PARAMS ((int regno)); +static void gdbtk_memory_changed PARAMS ((CORE_ADDR addr, int len)); +static void tracepoint_notify PARAMS ((struct tracepoint *, const char *)); +static void gdbtk_selected_frame_changed PARAMS ((int)); +static void gdbtk_context_change PARAMS ((int)); +static void gdbtk_error_begin PARAMS ((void)); +static void report_error (void); +static void gdbtk_annotate_signal (void); +static void gdbtk_set_hook (struct cmd_list_element *cmdblk); + +/* + * gdbtk_fputs can't be static, because we need to call it in gdbtk.c. + * See note there for details. + */ + +void gdbtk_fputs (const char *, struct ui_file *); +static int gdbtk_load_hash (const char *, unsigned long); +static void breakpoint_notify PARAMS ((struct breakpoint *, const char *)); + +/* + * gdbtk_add_hooks - add all the hooks to gdb. This will get called by the + * startup code to fill in the hooks needed by core gdb. + */ + +void +gdbtk_add_hooks (void) +{ + command_loop_hook = tk_command_loop; + call_command_hook = gdbtk_call_command; + set_hook = gdbtk_set_hook; + readline_begin_hook = gdbtk_readline_begin; + readline_hook = gdbtk_readline; + readline_end_hook = gdbtk_readline_end; + + print_frame_info_listing_hook = gdbtk_print_frame_info; + query_hook = gdbtk_query; + warning_hook = gdbtk_warning; + + create_breakpoint_hook = gdbtk_create_breakpoint; + delete_breakpoint_hook = gdbtk_delete_breakpoint; + modify_breakpoint_hook = gdbtk_modify_breakpoint; + + interactive_hook = gdbtk_interactive; + target_wait_hook = gdbtk_wait; + ui_load_progress_hook = gdbtk_load_hash; + + ui_loop_hook = x_event; + pre_add_symbol_hook = gdbtk_pre_add_symbol; + post_add_symbol_hook = gdbtk_post_add_symbol; + file_changed_hook = gdbtk_file_changed; + exec_file_display_hook = gdbtk_exec_file_display; + + create_tracepoint_hook = gdbtk_create_tracepoint; + delete_tracepoint_hook = gdbtk_delete_tracepoint; + modify_tracepoint_hook = gdbtk_modify_tracepoint; + trace_find_hook = gdbtk_trace_find; + trace_start_stop_hook = gdbtk_trace_start_stop; + + attach_hook = gdbtk_attach; + detach_hook = gdbtk_detach; + + register_changed_hook = gdbtk_register_changed; + memory_changed_hook = gdbtk_memory_changed; + selected_frame_level_changed_hook = gdbtk_selected_frame_changed; + context_hook = gdbtk_context_change; + + error_begin_hook = gdbtk_error_begin; + + annotate_signal_hook = gdbtk_annotate_signal; +} + +/* These control where to put the gdb output which is created by + {f}printf_{un}filtered and friends. gdbtk_fputs is the lowest + level of these routines and capture all output from the rest of + GDB. + + The reason to use the result_ptr rather than the gdbtk_interp's result + directly is so that a call_wrapper invoked function can preserve its result + across calls into Tcl which might be made in the course of the function's + execution. + + * result_ptr->obj_ptr is where to accumulate the result. + * GDBTK_TO_RESULT flag means the output goes to the gdbtk_tcl_fputs proc + instead of to the result_ptr. + * GDBTK_MAKES_LIST flag means add to the result as a list element. + + */ + +gdbtk_result *result_ptr = NULL; + + +/* This allows you to Tcl_Eval a tcl command which takes + a command word, and then a single argument. */ + +int +gdbtk_two_elem_cmd (cmd_name, argv1) + char *cmd_name; + char *argv1; +{ + char *command; + int result, flags_ptr, arg_len, cmd_len; + + arg_len = Tcl_ScanElement (argv1, &flags_ptr); + cmd_len = strlen (cmd_name); + command = malloc (arg_len + cmd_len + 2); + strcpy (command, cmd_name); + strcat (command, " "); + + Tcl_ConvertElement (argv1, command + cmd_len + 1, flags_ptr); + + result = Tcl_Eval (gdbtk_interp, command); + if (result != TCL_OK) + report_error (); + free (command); + return result; +} + +/* This handles all the output from gdb. All the gdb printf_xxx functions + * eventually end up here. The output is either passed to the result_ptr + * where it will go to the result of some gdbtk command, or passed to the + * Tcl proc gdbtk_tcl_fputs (where it is usually just dumped to the console + * window. + * + * The cases are: + * + * 1) result_ptr == NULL - This happens when some output comes from gdb which + * is not generated by a command in gdbtk-cmds, usually startup stuff. + * In this case we just route the data to gdbtk_tcl_fputs. + * 2) The GDBTK_TO_RESULT flag is set - The result is supposed to go to Tcl. + * We place the data into the result_ptr, either as a string, + * or a list, depending whether the GDBTK_MAKES_LIST bit is set. + * 3) The GDBTK_TO_RESULT flag is unset - We route the data to gdbtk_tcl_fputs + * UNLESS it was coming to gdb_stderr. Then we place it in the result_ptr + * anyway, so it can be dealt with. + * + */ + +void +gdbtk_fputs (ptr, stream) + const char *ptr; + struct ui_file *stream; +{ + in_fputs = 1; + + if (result_ptr != NULL) + { + if (result_ptr->flags & GDBTK_TO_RESULT) + { + if (result_ptr->flags & GDBTK_MAKES_LIST) + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewStringObj ((char *) ptr, -1)); + else + Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1); + } + else if (stream == gdb_stderr || result_ptr->flags & GDBTK_ERROR_ONLY) + { + if (result_ptr->flags & GDBTK_ERROR_STARTED) + Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1); + else + { + Tcl_SetStringObj (result_ptr->obj_ptr, (char *) ptr, -1); + result_ptr->flags |= GDBTK_ERROR_STARTED; + } + } + else + { + gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr); + if (result_ptr->flags & GDBTK_MAKES_LIST) + gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", " "); + } + } + else + { + gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr); + } + + in_fputs = 0; +} + +/* + * This routes all warnings to the Tcl function "gdbtk_tcl_warning". + */ + +static void +gdbtk_warning (warning, args) + const char *warning; + va_list args; +{ + char buf[200]; + + vsprintf (buf, warning, args); + gdbtk_two_elem_cmd ("gdbtk_tcl_warning", buf); +} + + +/* Error-handling function for all hooks */ +/* Hooks are not like tcl functions, they do not simply return */ +/* TCL_OK or TCL_ERROR. Also, the calling function typically */ +/* doesn't care about errors in the hook functions. Therefore */ +/* after every hook function, report_error should be called. */ +/* report_error can just call Tcl_BackgroundError() which will */ +/* pop up a messagebox, or it can silently log the errors through */ +/* the gdbtk dbug command. */ + +static void +report_error () +{ + TclDebug ('E', Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY)); + /* Tcl_BackgroundError(gdbtk_interp); */ +} + +/* + * This routes all ignorable warnings to the Tcl function + * "gdbtk_tcl_ignorable_warning". + */ + +void +gdbtk_ignorable_warning (class, warning) + const char *class; + const char *warning; +{ + char buf[512]; + sprintf (buf, "gdbtk_tcl_ignorable_warning {%s} {%s}", class, warning); + if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) + report_error (); +} + +static void +gdbtk_register_changed (regno) + int regno; +{ + if (Tcl_Eval (gdbtk_interp, "gdbtk_register_changed") != TCL_OK) + report_error (); +} + +static void +gdbtk_memory_changed (addr, len) + CORE_ADDR addr; + int len; +{ + if (Tcl_Eval (gdbtk_interp, "gdbtk_memory_changed") != TCL_OK) + report_error (); +} + + +/* This function is called instead of gdb's internal command loop. This is the + last chance to do anything before entering the main Tk event loop. + At the end of the command, we enter the main loop. */ + +static void +tk_command_loop () +{ + extern FILE *instream; + + /* We no longer want to use stdin as the command input stream */ + instream = NULL; + + if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_preloop") != TCL_OK) + { + char *msg; + + /* Force errorInfo to be set up propertly. */ + Tcl_AddErrorInfo (gdbtk_interp, ""); + + msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY); +#ifdef _WIN32 + MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL); +#else + fputs_unfiltered (msg, gdb_stderr); +#endif + } + +#ifdef _WIN32 + close_bfds (); +#endif + + Tk_MainLoop (); +} + +/* This hook is installed as the ui_loop_hook, which is used in several + * places to keep the gui alive (x_event runs gdbtk's event loop). Users + * include: + * - ser-tcp.c in socket reading code + * - ser-unix.c in serial port reading code + * - built-in simulators while executing + * + * x_event used to be called on SIGIO on the socket to the X server + * for unix. Unfortunately, Linux does not deliver SIGIO, so we resort + * to an elaborate scheme to keep the gui alive. + * + * For simulators and socket or serial connections on all hosts, we + * rely on ui_loop_hook (x_event) to keep us going. If the user + * requests a detach (as a result of pressing the stop button -- see + * comments before gdb_stop in gdbtk-cmds.c), it sets the global + * GDBTK_FORCE_DETACH, which is the value that x_event returns to + * it's caller. It is up to the caller of x_event to act on this + * information. + * + * For native unix, we simply set an interval timer which calls + * x_event to allow the debugger to run through the Tcl event + * loop. See comments before gdbtk_start_timer and gdb_stop_timer + * in gdbtk.c. + * + * For native windows (and a few other targets, like the v850 ICE), + * we rely on the target_wait loops to call ui_loop_hook to keep us alive. */ +int +x_event (signo) + int signo; +{ + static volatile int in_x_event = 0; + static Tcl_Obj *varname = NULL; + static int count = 0; + if (in_x_event || in_fputs) + return 0; + + in_x_event = 1; + gdbtk_force_detach = 0; + + /* Process pending events */ + while (Tcl_DoOneEvent (TCL_DONT_WAIT | TCL_ALL_EVENTS) != 0) + ; + + if (load_in_progress) + { + int val; + if (varname == NULL) + { +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 1 + Tcl_Obj *varnamestrobj = Tcl_NewStringObj ("download_cancel_ok", -1); + varname = Tcl_ObjGetVar2 (gdbtk_interp, varnamestrobj, NULL, TCL_GLOBAL_ONLY); +#else + varname = Tcl_GetObjVar2 (gdbtk_interp, "download_cancel_ok", NULL, TCL_GLOBAL_ONLY); +#endif + } + if ((Tcl_GetIntFromObj (gdbtk_interp, varname, &val) == TCL_OK) && val) + { + quit_flag = 1; +#ifdef REQUEST_QUIT + REQUEST_QUIT; +#else + if (immediate_quit) + quit (); +#endif + } + } + in_x_event = 0; + + return gdbtk_force_detach; +} + +/* VARARGS */ +static void +gdbtk_readline_begin (char *format,...) +{ + va_list args; + char buf[200]; + + va_start (args, format); + vsprintf (buf, format, args); + gdbtk_two_elem_cmd ("gdbtk_tcl_readline_begin", buf); +} + +static char * +gdbtk_readline (prompt) + char *prompt; +{ + int result; + +#ifdef _WIN32 + close_bfds (); +#endif + + result = gdbtk_two_elem_cmd ("gdbtk_tcl_readline", prompt); + + if (result == TCL_OK) + { + return (xstrdup (gdbtk_interp->result)); + } + else + { + gdbtk_fputs (gdbtk_interp->result, gdb_stdout); + gdbtk_fputs ("\n", gdb_stdout); + return (NULL); + } +} + +static void +gdbtk_readline_end () +{ + if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_readline_end") != TCL_OK) + report_error (); +} + +static void +gdbtk_call_command (cmdblk, arg, from_tty) + struct cmd_list_element *cmdblk; + char *arg; + int from_tty; +{ + running_now = 0; + if (cmdblk->class == class_run || cmdblk->class == class_trace) + { + + running_now = 1; + if (!No_Update) + Tcl_Eval (gdbtk_interp, "gdbtk_tcl_busy"); + (*cmdblk->function.cfunc) (arg, from_tty); + running_now = 0; + if (!No_Update) + Tcl_Eval (gdbtk_interp, "gdbtk_tcl_idle"); + } + else + (*cmdblk->function.cfunc) (arg, from_tty); +} + +/* Called after a `set' command succeeds. Runs the Tcl hook + `gdb_set_hook' with the full name of the variable (a Tcl list) as + the first argument and the new value as the second argument. */ + +static void +gdbtk_set_hook (struct cmd_list_element *cmdblk) +{ + Tcl_DString cmd; + char *p; + char buffer[30]; + + Tcl_DStringInit (&cmd); + Tcl_DStringAppendElement (&cmd, "run_hooks"); + Tcl_DStringAppendElement (&cmd, "gdb_set_hook"); + + /* Append variable name as sublist. */ + Tcl_DStringStartSublist (&cmd); + p = cmdblk->prefixname; + while (p && *p) + { + char *q = strchr (p, ' '); + char save; + if (q) + { + save = *q; + *q = '\0'; + } + Tcl_DStringAppendElement (&cmd, p); + if (q) + *q = save; + p = q + 1; + } + Tcl_DStringAppendElement (&cmd, cmdblk->name); + Tcl_DStringEndSublist (&cmd); + + switch (cmdblk->var_type) + { + case var_string_noescape: + case var_filename: + case var_enum: + case var_string: + Tcl_DStringAppendElement (&cmd, (*(char **) cmdblk->var + ? *(char **) cmdblk->var + : "(null)")); + break; + + case var_boolean: + Tcl_DStringAppendElement (&cmd, (*(int *) cmdblk->var ? "1" : "0")); + break; + + case var_uinteger: + case var_zinteger: + sprintf (buffer, "%u", *(unsigned int *) cmdblk->var); + Tcl_DStringAppendElement (&cmd, buffer); + break; + + case var_integer: + sprintf (buffer, "%d", *(int *) cmdblk->var); + Tcl_DStringAppendElement (&cmd, buffer); + break; + + default: + /* This case should already be trapped by the hook caller. */ + Tcl_DStringAppendElement (&cmd, "error"); + break; + } + + if (Tcl_Eval (gdbtk_interp, Tcl_DStringValue (&cmd)) != TCL_OK) + report_error (); + + Tcl_DStringFree (&cmd); +} + +/* The next three functions use breakpoint_notify to allow the GUI + * to handle creating, deleting and modifying breakpoints. These three + * functions are put into the appropriate gdb hooks in gdbtk_init. + */ + +static void +gdbtk_create_breakpoint (b) + struct breakpoint *b; +{ + breakpoint_notify (b, "create"); +} + +static void +gdbtk_delete_breakpoint (b) + struct breakpoint *b; +{ + breakpoint_notify (b, "delete"); +} + +static void +gdbtk_modify_breakpoint (b) + struct breakpoint *b; +{ + breakpoint_notify (b, "modify"); +} + +/* This is the generic function for handling changes in + * a breakpoint. It routes the information to the Tcl + * command "gdbtk_tcl_breakpoint" in the form: + * gdbtk_tcl_breakpoint action b_number b_address b_line b_file + * On error, the error string is written to gdb_stdout. + */ + +static void +breakpoint_notify (b, action) + struct breakpoint *b; + const char *action; +{ + char buf[256]; + int v; + struct symtab_and_line sal; + char *filename; + + if (b->type != bp_breakpoint) + return; + + /* We ensure that ACTION contains no special Tcl characters, so we + can do this. */ + sal = find_pc_line (b->address, 0); + filename = symtab_to_filename (sal.symtab); + if (filename == NULL) + filename = ""; + + sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s} {%s} %d %d", + action, b->number, (long) b->address, b->line_number, filename, + bpdisp[b->disposition], b->enable, b->thread); + + if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) + report_error (); +} + +int +gdbtk_load_hash (const char *section, unsigned long num) +{ + char buf[128]; + sprintf (buf, "Download::download_hash %s %ld", section, num); + if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) + report_error (); + return atoi (gdbtk_interp->result); +} + + +/* This hook is called whenever we are ready to load a symbol file so that + the UI can notify the user... */ +static void +gdbtk_pre_add_symbol (name) + char *name; +{ + gdbtk_two_elem_cmd ("gdbtk_tcl_pre_add_symbol", name); +} + +/* This hook is called whenever we finish loading a symbol file. */ +static void +gdbtk_post_add_symbol () +{ + if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_post_add_symbol") != TCL_OK) + report_error (); +} + +/* This hook function is called whenever we want to wait for the + target. */ + +static int +gdbtk_wait (pid, ourstatus) + int pid; + struct target_waitstatus *ourstatus; +{ + gdbtk_force_detach = 0; + gdbtk_start_timer (); + pid = target_wait (pid, ourstatus); + gdbtk_stop_timer (); + + return pid; +} + +/* + * This handles all queries from gdb. + * The first argument is a printf style format statement, the rest are its + * arguments. The resultant formatted string is passed to the Tcl function + * "gdbtk_tcl_query". + * It returns the users response to the query, as well as putting the value + * in the result field of the Tcl interpreter. + */ + +static int +gdbtk_query (query, args) + const char *query; + va_list args; +{ + char buf[200]; + long val; + + vsprintf (buf, query, args); + gdbtk_two_elem_cmd ("gdbtk_tcl_query", buf); + + val = atol (gdbtk_interp->result); + return val; +} + + +static void +gdbtk_print_frame_info (s, line, stopline, noerror) + struct symtab *s; + int line; + int stopline; + int noerror; +{ + current_source_symtab = s; + current_source_line = line; +} + +static void +gdbtk_create_tracepoint (tp) + struct tracepoint *tp; +{ + tracepoint_notify (tp, "create"); +} + +static void +gdbtk_delete_tracepoint (tp) + struct tracepoint *tp; +{ + tracepoint_notify (tp, "delete"); +} + +static void +gdbtk_modify_tracepoint (tp) + struct tracepoint *tp; +{ + tracepoint_notify (tp, "modify"); +} + +static void +tracepoint_notify (tp, action) + struct tracepoint *tp; + const char *action; +{ + char buf[256]; + int v; + struct symtab_and_line sal; + char *filename; + + /* We ensure that ACTION contains no special Tcl characters, so we + can do this. */ + sal = find_pc_line (tp->address, 0); + + filename = symtab_to_filename (sal.symtab); + if (filename == NULL) + filename = "N/A"; + sprintf (buf, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s} %d", action, tp->number, + (long) tp->address, sal.line, filename, tp->pass_count); + + if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) + report_error (); +} + +/* + * gdbtk_trace_find + * + * This is run by the trace_find_command. arg is the argument that was passed + * to that command, from_tty is 1 if the command was run from a tty, 0 if it + * was run from a script. It runs gdbtk_tcl_tfind_hook passing on these two + * arguments. + * + */ + +static void +gdbtk_trace_find (arg, from_tty) + char *arg; + int from_tty; +{ + Tcl_Obj *cmdObj; + + cmdObj = Tcl_NewListObj (0, NULL); + Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, + Tcl_NewStringObj ("gdbtk_tcl_trace_find_hook", -1)); + Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, Tcl_NewStringObj (arg, -1)); + Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, Tcl_NewIntObj (from_tty)); +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 1 + if (Tcl_GlobalEvalObj (gdbtk_interp, cmdObj) != TCL_OK) + report_error (); +#else + if (Tcl_EvalObj (gdbtk_interp, cmdObj, TCL_EVAL_GLOBAL) != TCL_OK) + report_error (); +#endif +} + +/* + * gdbtk_trace_start_stop + * + * This is run by the trace_start_command and trace_stop_command. + * The START variable determines which, 1 meaning trace_start was run, + * 0 meaning trace_stop was run. + * + */ + +static void +gdbtk_trace_start_stop (start, from_tty) + int start; + int from_tty; +{ + + if (start) + Tcl_GlobalEval (gdbtk_interp, "gdbtk_tcl_tstart"); + else + Tcl_GlobalEval (gdbtk_interp, "gdbtk_tcl_tstop"); + +} + +static void +gdbtk_selected_frame_changed (level) + int level; +{ + Tcl_UpdateLinkedVar (gdbtk_interp, "gdb_selected_frame_level"); +} + +/* Called when the current thread changes. */ +/* gdb_context is linked to the tcl variable "gdb_context_id" */ +static void +gdbtk_context_change (num) + int num; +{ + gdb_context = num; +} + +/* Called from file_command */ +static void +gdbtk_file_changed (filename) + char *filename; +{ + gdbtk_two_elem_cmd ("gdbtk_tcl_file_changed", filename); +} + +/* Called from exec_file_command */ +static void +gdbtk_exec_file_display (filename) + char *filename; +{ + gdbtk_two_elem_cmd ("gdbtk_tcl_exec_file_display", filename); +} + +/* Called from error_begin, this hook is used to warn the gui + about multi-line error messages */ +static void +gdbtk_error_begin () +{ + if (result_ptr != NULL) + result_ptr->flags |= GDBTK_ERROR_ONLY; +} + +/* notify GDBtk when a signal occurs */ +static void +gdbtk_annotate_signal () +{ + char buf[128]; + + /* Inform gui that the target has stopped. This is + a necessary stop button evil. We don't want signal notification + to interfere with the elaborate and painful stop button detach + timeout. */ + Tcl_Eval (gdbtk_interp, "gdbtk_stop_idle_callback"); + + sprintf (buf, "gdbtk_signal %s {%s}", target_signal_to_name (stop_signal), + target_signal_to_string (stop_signal)); + if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) + report_error (); +} + +static void +gdbtk_attach () +{ + if (Tcl_Eval (gdbtk_interp, "after idle \"update idletasks;gdbtk_attached\"") != TCL_OK) + { + report_error (); + } +} + +static void +gdbtk_detach () +{ + if (Tcl_Eval (gdbtk_interp, "gdbtk_detached") != TCL_OK) + { + report_error (); + } +} +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/generic/gdbtk-variable.c b/gdb/gdbtk/generic/gdbtk-variable.c new file mode 100644 index 00000000000..01aae3e12af --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk-variable.c @@ -0,0 +1,2417 @@ +/* Variable user interface layer for GDB, the GNU debugger. + Copyright 1999-2000 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "value.h" +#include "expression.h" +#include "frame.h" +#include "valprint.h" +#include "language.h" +#include "tui/tui-file.h" + +#include <tcl.h> +#include <tk.h> +#include "gdbtk.h" +#include "gdbtk-wrapper.h" + +#include <math.h> + +/* Enumeration for the format types */ +enum display_format +{ + FORMAT_NATURAL, /* What gdb actually calls 'natural' */ + FORMAT_BINARY, /* Binary display */ + FORMAT_DECIMAL, /* Decimal display */ + FORMAT_HEXADECIMAL, /* Hex display */ + FORMAT_OCTAL /* Octal display */ +}; + +/* Languages supported by this variable system. */ +enum vlanguage { vlang_c = 0, vlang_cplus, vlang_java, vlang_end }; + +/* Every variable keeps a linked list of its children, described + by the following structure. */ +struct variable_child { + + /* Pointer to the child's data */ + struct _gdb_variable *child; + + /* Pointer to the next child */ + struct variable_child *next; +}; + +/* Every root variable has one of these structures saved in its + gdb_variable. Members which must be free'd are noted. */ +struct variable_root { + + /* Alloc'd expression for this parent. */ + struct expression *exp; + + /* Block for which this expression is valid */ + struct block *valid_block; + + /* The frame for this expression */ + CORE_ADDR frame; + + /* Language info for this variable and its children */ + struct language_specific *lang; + + /* The gdb_variable for this root node. */ + struct _gdb_variable *root; +}; + +/* Every variable in the system has a structure of this type defined + for it. This structure holds all information necessary to manipulate + a particular object variable. Members which must be freed are noted. */ +struct _gdb_variable { + + /* Alloc'd name of the variable for this object.. If this variable is a + child, then this name will be the child's source name. + (bar, not foo.bar) */ + char *name; + + /* The alloc'd name for this variable's object. This is here for + convenience when constructing this object's children. */ + char *obj_name; + + /* Index of this variable in its parent or -1 */ + int index; + + /* The type of this variable. This may NEVER be NULL. */ + struct type *type; + + /* The value of this expression or subexpression. This may be NULL. */ + value_ptr value; + + /* Did an error occur evaluating the expression or getting its value? */ + int error; + + /* The number of (immediate) children this variable has */ + int num_children; + + /* If this object is a child, this points to its immediate parent. */ + struct _gdb_variable *parent; + + /* A list of this object's children */ + struct variable_child *children; + + /* Description of the root variable. Points to root variable for children. */ + struct variable_root *root; + + /* The format of the output for this object */ + enum display_format format; +}; + +typedef struct _gdb_variable gdb_variable; + +struct language_specific { + + /* The language of this variable */ + enum vlanguage language; + + /* The number of children of PARENT. */ + int (*number_of_children) PARAMS ((struct _gdb_variable *parent)); + + /* The name of the INDEX'th child of PARENT. */ + char *(*name_of_child) PARAMS ((struct _gdb_variable *parent, int index)); + + /* The value_ptr of the root variable ROOT. */ + value_ptr (*value_of_root) PARAMS ((struct _gdb_variable *root)); + + /* The value_ptr of the INDEX'th child of PARENT. */ + value_ptr (*value_of_child) PARAMS ((struct _gdb_variable *parent, int index)); + + /* The type of the INDEX'th child of PARENT. */ + struct type *(*type_of_child) PARAMS ((struct _gdb_variable *parent, int index)); + + /* Is VAR editable? */ + int (*variable_editable) PARAMS ((struct _gdb_variable *var)); + + /* The current value of VAR is returned in *OBJ. */ + int (*value_of_variable) PARAMS ((struct _gdb_variable *var, Tcl_Obj **obj)); +}; + +struct vstack { + gdb_variable *var; + struct vstack *next; +}; + +/* A little convenience enum for dealing with C++/Java */ +enum vsections { v_public = 0, v_private, v_protected }; + +/* + * Public functions defined in this file + */ + +int gdb_variable_init PARAMS ((Tcl_Interp *)); + +/* + * Private functions defined in this file + */ + +/* Entries into this file */ + +static int gdb_variable_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj *CONST[])); + +static int variable_obj_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj *CONST[])); + +/* Variable object subcommands */ +static int variable_create PARAMS ((Tcl_Interp *, int, Tcl_Obj *CONST[])); + +static void variable_delete PARAMS ((Tcl_Interp *, gdb_variable *)); + +static Tcl_Obj *variable_children PARAMS ((Tcl_Interp *, gdb_variable *)); + +static int variable_format PARAMS ((Tcl_Interp *, int, Tcl_Obj *CONST[], + gdb_variable *)); + +static int variable_type PARAMS ((Tcl_Interp *, int, Tcl_Obj *CONST[], + gdb_variable *)); + +static int variable_value PARAMS ((Tcl_Interp *, int, Tcl_Obj *CONST[], + gdb_variable *)); + +static int variable_editable PARAMS ((gdb_variable *)); + +static int my_value_of_variable PARAMS ((gdb_variable *var, Tcl_Obj **obj)); + +static Tcl_Obj *variable_update PARAMS ((Tcl_Interp *interp, gdb_variable *var)); + +/* Helper functions for the above subcommands. */ + +static gdb_variable *create_variable PARAMS ((char *name, CORE_ADDR frame)); + +static void delete_children PARAMS ((Tcl_Interp *, gdb_variable *, int)); + +static void install_variable PARAMS ((Tcl_Interp *, char *, gdb_variable *)); + +static void uninstall_variable PARAMS ((Tcl_Interp *, gdb_variable *)); + +static gdb_variable *child_exists PARAMS ((gdb_variable *, char *)); + +static gdb_variable *create_child PARAMS ((Tcl_Interp *, gdb_variable *, + int, char *)); +static char *name_of_child PARAMS ((gdb_variable *, int)); + +static int number_of_children PARAMS ((gdb_variable *)); + +static enum display_format variable_default_display PARAMS ((gdb_variable *)); + +static void save_child_in_parent PARAMS ((gdb_variable *, gdb_variable *)); + +static void remove_child_from_parent PARAMS ((gdb_variable *, gdb_variable *)); + +/* Utility routines */ + +static struct type *get_type PARAMS ((gdb_variable *var)); + +static struct type *get_type_deref PARAMS ((gdb_variable *var)); + +static struct type *get_target_type PARAMS ((struct type *)); + +static Tcl_Obj *get_call_output PARAMS ((void)); + +static void clear_gdb_output PARAMS ((void)); + +static int call_gdb_type_print PARAMS ((value_ptr)); + +static int call_gdb_val_print PARAMS ((value_ptr, int)); + +static void variable_fputs (const char *, struct ui_file *); + +static void null_fputs (const char *, struct ui_file *); + +static int my_value_equal PARAMS ((gdb_variable *, value_ptr)); + +static void vpush PARAMS ((struct vstack **pstack, gdb_variable *var)); + +static gdb_variable *vpop PARAMS ((struct vstack **pstack)); + +/* Language-specific routines. */ + +static value_ptr value_of_child PARAMS ((gdb_variable *parent, int index)); + +static value_ptr value_of_root PARAMS ((gdb_variable *var)); + +static struct type *type_of_child PARAMS ((gdb_variable *var)); + +static int type_changeable PARAMS ((gdb_variable *var)); + +static int c_number_of_children PARAMS ((gdb_variable *var)); + +static char *c_name_of_child PARAMS ((gdb_variable *parent, int index)); + +static value_ptr c_value_of_root PARAMS ((gdb_variable *var)); + +static value_ptr c_value_of_child PARAMS ((gdb_variable *parent, int index)); + +static struct type *c_type_of_child PARAMS ((gdb_variable *parent, int index)); + +static int c_variable_editable PARAMS ((gdb_variable *var)); + +static int c_value_of_variable PARAMS ((gdb_variable *var, Tcl_Obj **obj)); + +static int cplus_number_of_children PARAMS ((gdb_variable *var)); + +static void cplus_class_num_children PARAMS ((struct type *type, int children[3])); + +static char *cplus_name_of_child PARAMS ((gdb_variable *parent, int index)); + +static value_ptr cplus_value_of_root PARAMS ((gdb_variable *var)); + +static value_ptr cplus_value_of_child PARAMS ((gdb_variable *parent, int index)); + +static struct type *cplus_type_of_child PARAMS ((gdb_variable *parent, int index)); + +static int cplus_variable_editable PARAMS ((gdb_variable *var)); + +static int cplus_value_of_variable PARAMS ((gdb_variable *var, Tcl_Obj **obj)); + +static int java_number_of_children PARAMS ((gdb_variable *var)); + +static char *java_name_of_child PARAMS ((gdb_variable *parent, int index)); + +static value_ptr java_value_of_root PARAMS ((gdb_variable *var)); + +static value_ptr java_value_of_child PARAMS ((gdb_variable *parent, int index)); + +static struct type *java_type_of_child PARAMS ((gdb_variable *parent, int index)); + +static int java_variable_editable PARAMS ((gdb_variable *var)); + +static int java_value_of_variable PARAMS ((gdb_variable *var, Tcl_Obj **obj)); + +static enum vlanguage variable_language PARAMS ((gdb_variable *var)); + +static gdb_variable *new_variable PARAMS ((void)); + +static gdb_variable *new_root_variable (void); + +static void free_variable PARAMS ((gdb_variable *var)); + +/* String representations of gdb's format codes */ +char *format_string[] = {"natural", "binary", "decimal", "hexadecimal", "octal"}; + +/* Array of known source language routines. */ +static struct language_specific languages[vlang_end][sizeof(struct language_specific)] = { + { vlang_c, c_number_of_children, c_name_of_child, c_value_of_root, + c_value_of_child, c_type_of_child, c_variable_editable, + c_value_of_variable }, + { vlang_cplus, cplus_number_of_children, cplus_name_of_child, cplus_value_of_root, + cplus_value_of_child, cplus_type_of_child, cplus_variable_editable, + cplus_value_of_variable }, + { vlang_java, java_number_of_children, java_name_of_child, java_value_of_root, + java_value_of_child, java_type_of_child, java_variable_editable, + java_value_of_variable }}; + +/* Mappings of display_format enums to gdb's format codes */ +int format_code[] = {0, 't', 'd', 'x', 'o'}; + +/* This variable will hold the value of the output from gdb + for commands executed through call_gdb_* */ +static Tcl_Obj *fputs_obj; + +#if defined(FREEIF) +# undef FREEIF +#endif +#define FREEIF(x) if (x != NULL) free((char *) (x)) + +/* Is the variable X one of our "fake" children? */ +#define CPLUS_FAKE_CHILD(x) \ +((x) != NULL && (x)->type == NULL && (x)->value == NULL) + +/* Initialize the variable code. This function should be called once + to install and initialize the variable code into the interpreter. */ +int +gdb_variable_init (interp) + Tcl_Interp *interp; +{ + Tcl_Command result; + static int initialized = 0; + + if (!initialized) + { + result = Tcl_CreateObjCommand (interp, "gdb_variable", call_wrapper, + (ClientData) gdb_variable_command, NULL); + if (result == NULL) + return TCL_ERROR; + + initialized = 1; + } + + return TCL_OK; +} + +/* This function defines the "gdb_variable" command which is used to + create variable objects. Its syntax includes: + + gdb_variable create + gdb_variable create NAME + gdb_variable create -expr EXPR + gdb_variable create -frame FRAME + (it will also include permutations of the above options) + + NAME = name of object to create. If no NAME, then automatically create + a name + EXPR = the gdb expression for which to create a variable. This will + be the most common usage. + FRAME = the frame defining the scope of the variable. +*/ +static int +gdb_variable_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + static char *commands[] = { "create", "list", NULL }; + enum commands_enum { VARIABLE_CREATE, VARIABLE_LIST }; + int index, result; + + if (objc < 2) + { + Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0, + &index) != TCL_OK) + { + return TCL_ERROR; + } + + switch ((enum commands_enum) index) + { + case VARIABLE_CREATE: + result = variable_create (interp, objc - 2, objv + 2); + break; + + default: + return TCL_ERROR; + } + + return result; +} + +/* This function implements the actual object command for each + variable object that is created (and each of its children). + + Currently the following commands are implemented: + - delete delete this object and its children + - update update the variable and its children (root vars only) + - numChildren how many children does this object have + - children create the children and return a list of their objects + - name print out the name of this variable + - format query/set the display format of this variable + - type get the type of this variable + - value get/set the value of this variable + - editable is this variable editable? +*/ +static int +variable_obj_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + enum commands_enum { + VARIABLE_DELETE, + VARIABLE_NUM_CHILDREN, + VARIABLE_CHILDREN, + VARIABLE_FORMAT, + VARIABLE_TYPE, + VARIABLE_VALUE, + VARIABLE_NAME, + VARIABLE_EDITABLE, + VARIABLE_UPDATE + }; + static char *commands[] = { + "delete", + "numChildren", + "children", + "format", + "type", + "value", + "name", + "editable", + "update", + NULL + }; + gdb_variable *var = (gdb_variable *) clientData; + int index, result; + + if (objc < 2) + { + Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0, + &index) != TCL_OK) + return TCL_ERROR; + + result = TCL_OK; + switch ((enum commands_enum) index) + { + case VARIABLE_DELETE: + if (objc > 2) + { + int len; + char *s = Tcl_GetStringFromObj (objv[2], &len); + if (*s == 'c' && strncmp (s, "children", len) == 0) + { + delete_children (interp, var, 1); + break; + } + } + variable_delete (interp, var); + break; + + case VARIABLE_NUM_CHILDREN: + if (var->num_children == -1) + var->num_children = number_of_children (var); + + Tcl_SetObjResult (interp, Tcl_NewIntObj (var->num_children)); + break; + + case VARIABLE_CHILDREN: + { + Tcl_Obj *children = variable_children (interp, var); + Tcl_SetObjResult (interp, children); + } + break; + + case VARIABLE_FORMAT: + result = variable_format (interp, objc, objv, var); + break; + + case VARIABLE_TYPE: + result = variable_type (interp, objc, objv, var); + break; + + case VARIABLE_VALUE: + result = variable_value (interp, objc, objv, var); + break; + + case VARIABLE_NAME: + { + /* If var->name has "-" in it, it's because we + needed to escape periods in the name... */ + char *p, *name; + name = savestring (var->name, strlen (var->name)); + p = name; + while (*p != '\000') + { + if (*p == '-') + *p = '.'; + p++; + } + Tcl_SetObjResult (interp, Tcl_NewStringObj (name, -1)); + free (name); + } + break; + + case VARIABLE_EDITABLE: + Tcl_SetObjResult (interp, Tcl_NewIntObj (variable_editable (var))); + break; + + case VARIABLE_UPDATE: + /* Only root variables can be updated */ + if (var->parent == NULL) + { + Tcl_Obj *obj = variable_update (interp, var); + Tcl_SetObjResult (interp, obj); + } + result = TCL_OK; + break; + + default: + return TCL_ERROR; + } + + return result; +} + +/* + * Variable object construction/destruction + */ + +/* This function is responsible for processing the user's specifications + and constructing a variable object. */ +static int +variable_create (interp, objc, objv) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + enum create_opts { CREATE_EXPR, CREATE_FRAME }; + static char *create_options[] = { "-expr", "-frame", NULL }; + gdb_variable *var; + char *name; + char obj_name[31]; + int index; + static int id = 0; + CORE_ADDR frame = (CORE_ADDR) -1; + + /* REMINDER: This command may be invoked in the following ways: + gdb_variable create [NAME] [-expr EXPR] [-frame FRAME] + + NAME = name of object to create. If no NAME, then automatically create + a name + EXPR = the gdb expression for which to create a variable. This will + be the most common usage. + FRAME = the address of the frame defining the variable's scope + */ + name = NULL; + if (objc) + name = Tcl_GetStringFromObj (objv[0], NULL); + if (name == NULL || *name == '-') + { + /* generate a name for this object */ + id++; + sprintf (obj_name, "var%d", id); + } + else + { + /* specified name for object */ + strncpy (obj_name, name, 30); + objv++; + objc--; + } + + /* Run through all the possible options for this command */ + name = NULL; + while (objc > 0) + { + if (Tcl_GetIndexFromObj (interp, objv[0], create_options, "options", + 0, &index) != TCL_OK) + { + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + switch ((enum create_opts) index) + { + case CREATE_EXPR: + name = Tcl_GetStringFromObj (objv[1], NULL); + objc--; + objv++; + break; + + case CREATE_FRAME: + { + char *str; + str = Tcl_GetStringFromObj (objv[1], NULL); + frame = parse_and_eval_address (str); + objc--; + objv++; + } + break; + + default: + break; + } + + objc--; + objv++; + } + + /* Create the variable */ + var = create_variable (name, frame); + + if (var != NULL) + { + /* Install a command into the interpreter that represents this + object */ + install_variable (interp, obj_name, var); + Tcl_SetObjResult (interp, Tcl_NewStringObj (obj_name, -1)); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + + return TCL_OK; + } + + return TCL_ERROR; +} + +/* Fill out a gdb_variable structure for the (root) variable being constructed. */ +static gdb_variable * +create_variable (name, frame) + char *name; + CORE_ADDR frame; +{ + gdb_variable *var; + struct frame_info *fi, *old_fi; + struct block *block; + void (*old_fputs) (const char *, struct ui_file *); + gdb_result r; + + var = new_root_variable (); + if (name != NULL) + { + char *p; + enum vlanguage lang; + + /* Several of the GDB_* calls can cause messages to be displayed. We swallow + those here, because we don't need them (the "value" command will + show them). */ + old_fputs = fputs_unfiltered_hook; + fputs_unfiltered_hook = null_fputs; + + /* Parse and evaluate the expression, filling in as much + of the variable's data as possible */ + + /* Allow creator to specify context of variable */ + r = GDB_OK; + if (frame == (CORE_ADDR) -1) + fi = selected_frame; + else + r = GDB_find_frame_addr_in_frame_chain (frame, &fi); + + block = NULL; + if (fi != NULL) + r = GDB_get_frame_block (fi, &block); + + p = name; + innermost_block = NULL; + r = GDB_parse_exp_1 (&p, block, 0, &(var->root->exp)); + if (r != GDB_OK) + { + free_variable (var); + + /* Restore the output hook to normal */ + fputs_unfiltered_hook = old_fputs; + + return NULL; + } + + /* Don't allow variables to be created for types. */ + if (var->root->exp->elts[0].opcode == OP_TYPE) + { + free_variable (var); + + /* Restore the output hook to normal */ + fputs_unfiltered_hook = old_fputs; + + printf_unfiltered ("Attempt to use a type name as an expression."); + return NULL; + } + + var->format = variable_default_display (var); + var->root->valid_block = innermost_block; + var->name = savestring (name, strlen (name)); + + /* When the frame is different from the current frame, + we must select the appropriate frame before parsing + the expression, otherwise the value will not be current. + Since select_frame is so benign, just call it for all cases. */ + if (fi != NULL) + { + var->root->frame = FRAME_FP (fi); + old_fi = selected_frame; + GDB_select_frame (fi, -1); + } + + if (GDB_evaluate_expression (var->root->exp, &var->value) == GDB_OK) + { + release_value (var->value); + if (VALUE_LAZY (var->value)) + GDB_value_fetch_lazy (var->value); + } + else + var->value = evaluate_type (var->root->exp); + + var->type = VALUE_TYPE (var->value); + + /* Set language info */ + lang = variable_language (var); + var->root->lang = languages[lang]; + + /* Set ourselves as our root */ + var->root->root = var; + + /* Reset the selected frame */ + if (fi != NULL) + GDB_select_frame (old_fi, -1); + + + /* Restore the output hook to normal */ + fputs_unfiltered_hook = old_fputs; + } + + return var; +} + +/* Install the given variable VAR into the tcl interpreter with + the object name NAME. */ +static void +install_variable (interp, name, var) + Tcl_Interp *interp; + char *name; + gdb_variable *var; +{ + var->obj_name = savestring (name, strlen (name)); + Tcl_CreateObjCommand (interp, name, variable_obj_command, + (ClientData) var, NULL); +} + +/* Unistall the object VAR in the tcl interpreter. */ +static void +uninstall_variable (interp, var) + Tcl_Interp *interp; + gdb_variable *var; +{ + Tcl_DeleteCommand (interp, var->obj_name); +} + +/* Delete the variable object VAR and its children */ +static void +variable_delete (interp, var) + Tcl_Interp *interp; + gdb_variable *var; +{ + /* Delete any children of this variable, too. */ + delete_children (interp, var, 0); + + /* If this variable has a parent, remove it from its parent's list */ + if (var->parent != NULL) + { + remove_child_from_parent (var->parent, var); + } + + uninstall_variable (interp, var); + + /* Free memory associated with this variable */ + free_variable (var); +} + +/* Free any allocated memory associated with VAR. */ +static void free_variable (var) + gdb_variable *var; +{ + /* Free the expression if this is a root variable. */ + if (var->root->root == var) + { + free_current_contents ((char **) &var->root->exp); + FREEIF (var->root); + } + + FREEIF (var->name); + FREEIF (var->obj_name); + FREEIF (var); +} + +/* + * Child construction/destruction + */ + +/* Delete the children associated with the object VAR. If NOTIFY is set, + notify the parent object that this child was deleted. This is used as + a small optimization when deleting variables and their children. If the + parent is also being deleted, don't bother notifying it that its children + are being deleted. */ +static void +delete_children (interp, var, notify) + Tcl_Interp *interp; + gdb_variable *var; + int notify; +{ + struct variable_child *vc; + struct variable_child *next; + + for (vc = var->children; vc != NULL; vc = next) + { + if (!notify) + vc->child->parent = NULL; + variable_delete (interp, vc->child); + next = vc->next; + free (vc); + } +} + +/* Return the number of children for a given variable. + The result of this function is defined by the language + implementation. The number of children returned by this function + is the number of children that the user will see in the variable + display. */ +static int +number_of_children (var) + gdb_variable *var; +{ + return (*var->root->lang->number_of_children) (var);; +} + +/* Return a list of all the children of VAR, creating them if necessary. */ +static Tcl_Obj * +variable_children (interp, var) + Tcl_Interp *interp; + gdb_variable *var; +{ + Tcl_Obj *list; + gdb_variable *child; + char *name; + int i; + + list = Tcl_NewListObj (0, NULL); + if (var->num_children == -1) + var->num_children = number_of_children (var); + + for (i = 0; i < var->num_children; i++) + { + /* check if child exists */ + name = name_of_child (var, i); + child = child_exists (var, name); + if (child == NULL) + child = create_child (interp, var, i, name); + + if (child != NULL) + Tcl_ListObjAppendElement (NULL, list, Tcl_NewStringObj (child->obj_name, -1)); + } + + return list; +} + +/* Does a child with the name NAME exist in VAR? If so, return its data. + If not, return NULL. */ +static gdb_variable * +child_exists (var, name) + gdb_variable *var; /* Parent */ + char *name; /* name of child */ +{ + struct variable_child *vc; + + for (vc = var->children; vc != NULL; vc = vc->next) + { + if (STREQ (vc->child->name, name)) + return vc->child; + } + + return NULL; +} + +/* Create and install a child of the parent of the given name */ +static gdb_variable * +create_child (interp, parent, index, name) + Tcl_Interp *interp; + gdb_variable *parent; + int index; + char *name; +{ + gdb_variable *child; + char *childs_name; + + child = new_variable (); + + /* name is allocated by name_of_child */ + child->name = name; + child->index = index; + child->value = value_of_child (parent, index); + if (child->value == NULL || parent->error) + child->error = 1; + child->parent = parent; + child->root = parent->root; + childs_name = (char *) xmalloc ((strlen (parent->obj_name) + strlen (name) + 2) + * sizeof (char)); + sprintf (childs_name, "%s.%s", parent->obj_name, name); + install_variable (interp, childs_name, child); + free (childs_name); + + /* Save a pointer to this child in the parent */ + save_child_in_parent (parent, child); + + /* Note the type of this child */ + child->type = type_of_child (child); + + return child; +} + +/* Save CHILD in the PARENT's data. */ +static void +save_child_in_parent (parent, child) + gdb_variable *parent; + gdb_variable *child; +{ + struct variable_child *vc; + + /* Insert the child at the top */ + vc = parent->children; + parent->children = + (struct variable_child *) xmalloc (sizeof (struct variable_child)); + + parent->children->next = vc; + parent->children->child = child; +} + +/* Remove the CHILD from the PARENT's list of children. */ +static void +remove_child_from_parent (parent, child) + gdb_variable *parent; + gdb_variable *child; +{ + struct variable_child *vc, *prev; + + /* Find the child in the parent's list */ + prev = NULL; + for (vc = parent->children; vc != NULL; ) + { + if (vc->child == child) + break; + prev = vc; + vc = vc->next; + } + + if (prev == NULL) + parent->children = vc->next; + else + prev->next = vc->next; + +} + +/* What is the name of the INDEX'th child of VAR? Returns a malloc'd string. */ +static char * +name_of_child (var, index) + gdb_variable *var; + int index; +{ + return (*var->root->lang->name_of_child) (var, index); +} + +/* Update the values for a variable and its children. This is a + two-pronged attack. First, re-parse the value for the root's + expression to see if it's changed. Then go all the way + through its children, reconstructing them and noting if they've + changed. + + Only root variables can be updated... */ +static Tcl_Obj * +variable_update (interp, var) + Tcl_Interp *interp; + gdb_variable *var; +{ + void (*old_hook) (const char *, struct ui_file *); + Tcl_Obj *changed; + gdb_variable *v; + value_ptr new; + struct vstack *stack = NULL; + struct frame_info *old_fi; + + /* Initialize a stack */ + vpush (&stack, NULL); + + /* Save the selected stack frame, since we will need to change it + in order to evaluate expressions. */ + old_fi = selected_frame; + + /* evaluate_expression can output errors to the screen, + so swallow them here. */ + old_hook = fputs_unfiltered_hook; + fputs_unfiltered_hook = null_fputs; + + changed = Tcl_NewListObj (0, NULL); + + /* Update the root variable. value_of_root can return NULL + if the variable is no longer around, i.e. we stepped out of + the frame in which a local existed. */ + new = value_of_root (var); + if (new == NULL) + return changed; + + if (!my_value_equal (var, new)) + { + /* Note that it's changed There a couple of exceptions here, + though. We don't want some types to be reported as "changed". */ + if (type_changeable (var)) + Tcl_ListObjAppendElement (interp, changed, Tcl_NewStringObj (var->obj_name, -1)); + } + + /* We must always keep around the new value for this root + variable expression, or we lose the updated children! */ + value_free (var->value); + var->value = new; + + /* Push the root's children */ + if (var->children != NULL) + { + struct variable_child *c; + for (c = var->children; c != NULL; c = c->next) + vpush (&stack, c->child); + } + + /* Walk through the children, reconstructing them all. */ + v = vpop (&stack); + while (v != NULL) + { + /* Push any children */ + if (v->children != NULL) + { + struct variable_child *c; + for (c = v->children; c != NULL; c = c->next) + vpush (&stack, c->child); + } + + /* Update this variable */ + new = value_of_child (v->parent, v->index); + if (type_changeable (v) && !my_value_equal (v, new)) + { + /* Note that it's changed */ + Tcl_ListObjAppendElement (interp, changed, + Tcl_NewStringObj (v->obj_name, -1)); + } + + /* We must always keep new values, since children depend on it. */ + if (v->value != NULL) + value_free (v->value); + v->value = new; + + /* Get next child */ + v = vpop (&stack); + } + + /* Restore the original fputs_hook. */ + fputs_unfiltered_hook = old_hook; + + /* Restore selected frame */ + GDB_select_frame (old_fi, -1); + + return changed; +} + +/* What is the type of VAR? */ +static struct type * +type_of_child (var) + gdb_variable *var; +{ + + /* If the child had no evaluation errors, var->value + will be non-NULL and contain a valid type. */ + if (var->value != NULL) + return VALUE_TYPE (var->value); + + /* Otherwise, we must compute the type. */ + return (*var->root->lang->type_of_child) (var->parent, var->index); +} + +/* What is the value_ptr for the INDEX'th child of PARENT? */ +static value_ptr +value_of_child (parent, index) + gdb_variable *parent; + int index; +{ + value_ptr value; + void (*old_hook) (const char *, struct ui_file *); + + /* Same deal here as before. GDB can output error messages to the + screen while it attempts to work its way through the tree. */ + old_hook = fputs_unfiltered_hook; + fputs_unfiltered_hook = null_fputs; + + value = (*parent->root->lang->value_of_child) (parent, index); + + /* If we're being lazy, fetch the real value of the variable. */ + if (value != NULL && VALUE_LAZY (value)) + GDB_value_fetch_lazy (value); + + /* Restore output hook */ + fputs_unfiltered_hook = old_hook; + + return value; +} + +/* What is the value_ptr of the root variable VAR? */ +static value_ptr +value_of_root (var) + gdb_variable *var; +{ + return (*var->root->lang->value_of_root) (var); +} + +/* This implements the format object command allowing + the querying or setting of the object's display format. */ +static int +variable_format (interp, objc, objv, var) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + gdb_variable *var; +{ + + if (objc > 2) + { + /* Set the format of VAR to given format */ + int len; + char *fmt = Tcl_GetStringFromObj (objv[2], &len); + if (STREQN (fmt, "natural", len)) + var->format = FORMAT_NATURAL; + else if (STREQN (fmt, "binary", len)) + var->format = FORMAT_BINARY; + else if (STREQN (fmt, "decimal", len)) + var->format = FORMAT_DECIMAL; + else if (STREQN (fmt, "hexadecimal", len)) + var->format = FORMAT_HEXADECIMAL; + else if (STREQN (fmt, "octal", len)) + var->format = FORMAT_OCTAL; + else + { + Tcl_Obj *obj = Tcl_NewStringObj (NULL, 0); + Tcl_AppendStringsToObj (obj, "unknown display format \"", + fmt, "\": must be: \"natural\", \"binary\"" + ", \"decimal\", \"hexadecimal\", or \"octal\"", + NULL); + Tcl_SetObjResult (interp, obj); + return TCL_ERROR; + } + } + else + { + /* Report the current format */ + Tcl_Obj *fmt; + + fmt = Tcl_NewStringObj (format_string [(int) var->format], -1); + Tcl_SetObjResult (interp, fmt); + } + + return TCL_OK; +} + +/* What is the default display for this variable? We assume that + everything is "natural". Any exceptions? */ +static enum display_format +variable_default_display (var) + gdb_variable *var; +{ + return FORMAT_NATURAL; +} + +/* This function implements the type object command, which returns the type of a + variable in the interpreter (or an error). */ +static int +variable_type (interp, objc, objv, var) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + gdb_variable *var; +{ + int result; + value_ptr val; + char *first, *last, *string; + Tcl_RegExp regexp; + gdb_result r; + + /* For the "fake" variables, do not return a type. (It's type is + NULL, too.) */ + if (CPLUS_FAKE_CHILD (var)) + { + Tcl_ResetResult (interp); + return TCL_OK; + } + + /* To print the type, we simply create a zero value_ptr and + cast it to our type. We then typeprint this variable. */ + val = value_zero (var->type, not_lval); + result = call_gdb_type_print (val); + if (result == TCL_OK) + { + string = xstrdup (Tcl_GetStringFromObj (get_call_output (), NULL)); + first = string; + + /* gdb will print things out like "struct {...}" for anonymous structs. + In gui-land, we don't want the {...}, so we strip it here. */ + regexp = Tcl_RegExpCompile (interp, "{...}"); + if (Tcl_RegExpExec (interp, regexp, string, first)) + { + /* We have an anonymous struct/union/class/enum */ + Tcl_RegExpRange (regexp, 0, &first, &last); + if (*(first - 1) == ' ') + first--; + *first = '\0'; + } + + Tcl_SetObjResult (interp, Tcl_NewStringObj (string, -1)); + FREEIF (string); + return TCL_OK; + } + + Tcl_SetObjResult (interp, get_call_output ()); + return result; +} + +/* This function implements the value object command, which allows an object's + value to be queried or set. */ +static int +variable_value (interp, objc, objv, var) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + gdb_variable *var; +{ + int result; + struct type *type; + value_ptr val; + Tcl_Obj *str; + gdb_result r; + int real_addressprint; + int offset = 0; + + /* If we're setting the value of the variable, objv[2] will contain the + variable's new value. We need to first construct a legal expression + for this -- ugh! */ + if (objc > 2) + { + /* Does this cover all the bases? */ + struct expression *exp; + value_ptr value; + int saved_input_radix = input_radix; + + if (variable_editable (var) && !var->error) + { + char *s; + int i; + value_ptr temp; + + input_radix = 10; /* ALWAYS reset to decimal temporarily */ + s = Tcl_GetStringFromObj (objv[2], NULL); + r = GDB_parse_exp_1 (&s, 0, 0, &exp); + if (r != GDB_OK) + return TCL_ERROR; + if (GDB_evaluate_expression (exp, &value) != GDB_OK) + return TCL_ERROR; + + /* If our parent is "public", "private", or "protected", we could + be asking to modify the value of a baseclass. If so, we need to + adjust our address by the offset of our baseclass in the subclass, + since VALUE_ADDRESS (var->value) points at the start of the subclass. + For some reason, value_cast doesn't take care of this properly. */ + temp = var->value; + if (var->parent != NULL && CPLUS_FAKE_CHILD (var->parent)) + { + gdb_variable *super, *sub; + struct type *type; + super = var->parent->parent; + sub = super->parent; + if (sub != NULL) + { + /* Yes, it is a baseclass */ + type = get_type_deref (sub); + + if (super->index < TYPE_N_BASECLASSES (type)) + { + temp = value_copy (var->value); + for (i = 0; i < super->index; i++) + offset += TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)); + } + } + } + + VALUE_ADDRESS (temp) += offset; + val = value_assign (temp, value); + VALUE_ADDRESS (val) -= offset; + value_free (var->value); + release_value (val); + var->value = val; + input_radix = saved_input_radix; + } + + Tcl_ResetResult (interp); + return TCL_OK; + } + + result = my_value_of_variable (var, &str); + Tcl_SetObjResult (interp, str); + + return result; +} + +/* GDB already has a command called "value_of_variable". Sigh. */ +static int +my_value_of_variable (var, obj) + gdb_variable *var; + Tcl_Obj **obj; +{ + return (*var->root->lang->value_of_variable) (var, obj); +} + +/* Is this variable editable? Use the variable's type to make + this determination. */ +static int +variable_editable (var) + gdb_variable *var; +{ + return (*var->root->lang->variable_editable) (var); +} + +/* + * Call stuff. These functions are used to capture the output of gdb commands + * without going through the tcl interpreter. + */ + +/* Retrieve gdb output in the buffer since last call. */ +static Tcl_Obj * +get_call_output () +{ + /* Clear the error flags, in case we errored. */ + if (result_ptr != NULL) + result_ptr->flags &= ~GDBTK_ERROR_ONLY; + return fputs_obj; +} + +/* Clear the output of the buffer. */ +static void +clear_gdb_output () +{ + if (fputs_obj != NULL) + Tcl_DecrRefCount (fputs_obj); + + fputs_obj = Tcl_NewStringObj (NULL, -1); + Tcl_IncrRefCount (fputs_obj); +} + +/* Call the gdb command "type_print", retaining its output in the buffer. */ +static int +call_gdb_type_print (val) + value_ptr val; +{ + void (*old_hook) (const char *, struct ui_file *); + int result; + + /* Save the old hook and install new hook */ + old_hook = fputs_unfiltered_hook; + fputs_unfiltered_hook = variable_fputs; + + /* Call our command with our args */ + clear_gdb_output (); + + + if (GDB_type_print (val, "", gdb_stdout, -1) == GDB_OK) + result = TCL_OK; + else + result = TCL_ERROR; + + /* Restore fputs hook */ + fputs_unfiltered_hook = old_hook; + + return result; +} + +/* Call the gdb command "val_print", retaining its output in the buffer. */ +static int +call_gdb_val_print (val, format) + value_ptr val; + int format; +{ + void (*old_hook) (const char *, struct ui_file *); + gdb_result r; + int result; + + /* Save the old hook and install new hook */ + old_hook = fputs_unfiltered_hook; + fputs_unfiltered_hook = variable_fputs; + + /* Call our command with our args */ + clear_gdb_output (); + + if (VALUE_LAZY (val)) + { + r = GDB_value_fetch_lazy (val); + if (r != GDB_OK) + { + fputs_unfiltered_hook = old_hook; + return TCL_ERROR; + } + } + r = GDB_val_print (VALUE_TYPE (val), VALUE_CONTENTS_RAW (val), VALUE_ADDRESS (val), + gdb_stdout, format, 1, 0, 0); + if (r == GDB_OK) + result = TCL_OK; + else + result = TCL_ERROR; + + /* Restore fputs hook */ + fputs_unfiltered_hook = old_hook; + + return result; +} + +/* The fputs_unfiltered_hook function used to save the output from one of the + call commands in this file. */ +static void +variable_fputs (text, stream) + const char *text; + struct ui_file *stream; +{ + /* Just append everything to the fputs_obj... Issues with stderr/stdout? */ + Tcl_AppendToObj (fputs_obj, (char *) text, -1); +} + +/* Empty handler for the fputs_unfiltered_hook. Set the hook to this function + whenever the output is irrelevent. */ +static void +null_fputs (text, stream) + const char *text; + struct ui_file *stream; +{ + return; +} + +/* + * Miscellaneous utility functions. + */ + +/* This returns the type of the variable. This skips past typedefs + and returns the real type of the variable. It also dereferences + pointers and references. */ +static struct type * +get_type (var) + gdb_variable *var; +{ + struct type *type = NULL; + type = var->type; + + while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF) + type = TYPE_TARGET_TYPE (type); + + return type; +} + +/* This returns the type of the variable, dereferencing pointers, too. */ +static struct type * +get_type_deref (var) + gdb_variable *var; +{ + struct type *type = NULL; + + type = get_type (var); + + if (type != NULL && (TYPE_CODE (type) == TYPE_CODE_PTR + || TYPE_CODE (type) == TYPE_CODE_REF)) + type = get_target_type (type); + + return type; +} + +/* This returns the target type (or NULL) of TYPE, also skipping + past typedefs, just like get_type (). */ +static struct type * +get_target_type (type) + struct type *type; +{ + if (type != NULL) + { + type = TYPE_TARGET_TYPE (type); + while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF) + type = TYPE_TARGET_TYPE (type); + } + + return type; +} + +/* Get the language of variable VAR. */ +static enum vlanguage +variable_language (var) + gdb_variable *var; +{ + enum vlanguage lang; + + switch (var->root->exp->language_defn->la_language) + { + default: + case language_c: + lang = vlang_c; + break; + case language_cplus: + lang = vlang_cplus; + break; + case language_java: + lang = vlang_java; + break; + } + + return lang; +} + +/* This function is similar to gdb's value_equal, except that this + one is "safe" -- it NEVER longjmps. It determines if the VAR's + value is the same as VAL2. */ +static int +my_value_equal (var, val2) + gdb_variable *var; + value_ptr val2; +{ + int r, err1, err2; + gdb_result result; + + /* Special case: NULL values. If both are null, say + they're equal. */ + if (var->value == NULL && val2 == NULL) + return 1; + else if (var->value == NULL || val2 == NULL) + return 0; + + /* This is bogus, but unfortunately necessary. We must know + exactly what caused an error -- reading var->val or val2 -- so + that we can really determine if we think that something has changed. */ + err1 = 0; + err2 = 0; + result = GDB_value_equal (var->value, var->value, &r); + if (result != GDB_OK) + err1 = 1; + + result = GDB_value_equal (val2, val2, &r); + if (result != GDB_OK) + err2 = 1; + + if (err1 != err2) + return 0; + + if (GDB_value_equal (var->value, val2, &r) != GDB_OK) + { + /* An error occurred, this could have happened if + either val1 or val2 errored. ERR1 and ERR2 tell + us which of these it is. If both errored, then + we assume nothing has changed. If one of them is + valid, though, then something has changed. */ + if (err1 == err2) + { + /* both the old and new values caused errors, so + we say the value did not change */ + /* This is indeterminate, though. Perhaps we should + be safe and say, yes, it changed anyway?? */ + return 1; + } + else + { + /* err2 replaces var->error since this new value + WILL replace the old one. */ + var->error = err2; + return 0; + } + } + + return r; +} + +static void +vpush (pstack, var) + struct vstack **pstack; + gdb_variable *var; +{ + struct vstack *s; + + s = (struct vstack *) xmalloc (sizeof (struct vstack)); + s->var = var; + s->next = *pstack; + *pstack = s; +} + +static gdb_variable * +vpop (pstack) + struct vstack **pstack; +{ + struct vstack *s; + gdb_variable *v; + + if ((*pstack)->var == NULL && (*pstack)->next == NULL) + return NULL; + + s = *pstack; + v = s->var; + *pstack = (*pstack)->next; + free (s); + + return v; +} + +/* Is VAR something that can change? Depending on language, + some variable's values never change. For example, + struct and unions never change values. */ +static int +type_changeable (var) + gdb_variable *var; +{ + int r; + struct type *type; + + r = 0; + if (!CPLUS_FAKE_CHILD (var)) + { + type = get_type (var); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + r = 0; + break; + + default: + r = 1; + } + } + + return r; +} + +/* Allocate memory and initialize a new variable */ +static gdb_variable * +new_variable () +{ + gdb_variable *var; + + var = (gdb_variable *) xmalloc (sizeof (gdb_variable)); + var->name = NULL; + var->obj_name = NULL; + var->index = -1; + var->type = NULL; + var->value = NULL; + var->error = 0; + var->num_children = -1; + var->parent = NULL; + var->children = NULL; + var->format = 0; + var->root = NULL; + + return var; +} + +/* Allocate memory and initialize a new root variable */ +static gdb_variable * +new_root_variable (void) +{ + gdb_variable *var = new_variable (); + var->root = (struct variable_root *) xmalloc (sizeof (struct variable_root));; + var->root->lang = NULL; + var->root->exp = NULL; + var->root->valid_block = NULL; + var->root->frame = (CORE_ADDR) -1; + var->root->root = NULL; + + return var; +} + +/* + * Language-dependencies + */ + +/* C */ +static int +c_number_of_children (var) + gdb_variable *var; +{ + struct type *type; + struct type *target; + int children; + + type = get_type (var); + target = get_target_type (type); + children = 0; + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (target) > 0 + && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED) + children = TYPE_LENGTH (type) / TYPE_LENGTH (target); + else + children = -1; + break; + + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + children = TYPE_NFIELDS (type); + break; + + case TYPE_CODE_PTR: + /* This is where things get compilcated. All pointers have one child. + Except, of course, for struct and union ptr, which we automagically + dereference for the user and function ptrs, which have no children. */ + switch (TYPE_CODE (target)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + children = TYPE_NFIELDS (target); + break; + + case TYPE_CODE_FUNC: + children = 0; + break; + + default: + /* Don't dereference char* or void*. */ + if (TYPE_NAME (target) != NULL + && (STREQ (TYPE_NAME (target), "char") + || STREQ (TYPE_NAME (target), "void"))) + children = 0; + else + children = 1; + } + break; + + default: + break; + } + + return children; +} + +static char * +c_name_of_child (parent, index) + gdb_variable *parent; + int index; +{ + struct type *type; + struct type *target; + char *name; + char *string; + + type = get_type (parent); + target = get_target_type (type); + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + { + /* We never get here unless parent->num_children is greater than 0... */ + int len = 1; + while ((int) pow ((double) 10, (double) len) < index) + len++; + name = (char *) xmalloc (1 + len * sizeof (char)); + sprintf (name, "%d", index); + } + break; + + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + string = TYPE_FIELD_NAME (type, index); + name = savestring (string, strlen (string)); + break; + + case TYPE_CODE_PTR: + switch (TYPE_CODE (target)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + string = TYPE_FIELD_NAME (target, index); + name = savestring (string, strlen (string)); + break; + + default: + name = (char *) xmalloc ((strlen (parent->name) + 2) * sizeof (char)); + sprintf (name, "*%s", parent->name); + break; + } + } + + return name; +} + +static value_ptr +c_value_of_root (var) + gdb_variable *var; +{ + value_ptr value, new_val; + struct frame_info *fi, *old_fi; + int within_scope; + gdb_result r; + + /* Determine whether the variable is still around. */ + if (var->root->valid_block == NULL) + within_scope = 1; + else + { + GDB_reinit_frame_cache (); + r = GDB_find_frame_addr_in_frame_chain (var->root->frame, &fi); + if (r != GDB_OK) + fi = NULL; + within_scope = fi != NULL; + /* FIXME: GDB_select_frame could fail */ + if (within_scope) + GDB_select_frame (fi, -1); + } + + if (within_scope) + { + struct type *type = get_type (var); + if (GDB_evaluate_expression (var->root->exp, &new_val) == GDB_OK) + { + if (VALUE_LAZY (new_val)) + { + if (GDB_value_fetch_lazy (new_val) != GDB_OK) + var->error = 1; + else + var->error = 0; + } + } + else + var->error = 1; + + release_value (new_val); + return new_val; + } + + return NULL; +} + +static value_ptr +c_value_of_child (parent, index) + gdb_variable *parent; + int index; +{ + value_ptr value, temp; + struct type *type, *target; + gdb_result r; + char *name; + + type = get_type (parent); + target = get_target_type (type); + name = name_of_child (parent, index); + temp = parent->value; + value = NULL; + + if (temp != NULL) + { + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + r = GDB_value_slice (temp, index, 1, &value); + r = GDB_value_coerce_array (value, &temp); + r = GDB_value_ind (temp, &value); + break; + + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + r = GDB_value_struct_elt (&temp, NULL, name, NULL, "vstructure", &value); + break; + + case TYPE_CODE_PTR: + switch (TYPE_CODE (target)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + r = GDB_value_struct_elt (&temp, NULL, name, NULL, "vstructure", &value); + break; + + default: + r = GDB_value_ind (temp, &value); + break; + } + break; + + default: + break; + } + } + + if (value != NULL) + release_value (value); + + return value; +} + +static struct type * +c_type_of_child (parent, index) + gdb_variable *parent; + int index; +{ + struct type *type; + gdb_result r; + char *name = name_of_child (parent, index); + + switch (TYPE_CODE (parent->type)) + { + case TYPE_CODE_ARRAY: + type = TYPE_TARGET_TYPE (parent->type); + break; + + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + type = lookup_struct_elt_type (parent->type, name, 0); + break; + + case TYPE_CODE_PTR: + switch (TYPE_CODE (TYPE_TARGET_TYPE (parent->type))) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + type = lookup_struct_elt_type (parent->type, name, 0); + break; + + default: + type = TYPE_TARGET_TYPE (parent->type); + break; + } + + default: + break; + } + + return type; +} + +static int +c_variable_editable (var) + gdb_variable *var; +{ + switch (TYPE_CODE (get_type (var))) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_ARRAY: + case TYPE_CODE_FUNC: + case TYPE_CODE_MEMBER: + case TYPE_CODE_METHOD: + return 0; + break; + + default: + return 1; + break; + } +} + +static int +c_value_of_variable (var, obj) + gdb_variable *var; + Tcl_Obj **obj; +{ + struct type *type; + value_ptr val; + int result; + + if (var->value != NULL) + val = var->value; + else + { + /* This can happen if we attempt to get the value of a struct + member when the parent is an invalid pointer. + + GDB reports the error as the error derived from accessing the + parent, but we don't have access to that here... */ + *obj = Tcl_NewStringObj ("???", -1); + return TCL_ERROR; + } + + /* BOGUS: if val_print sees a struct/class, it will print out its + children instead of "{...}" */ + type = get_type (var); + result = TCL_OK; + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + *obj = Tcl_NewStringObj ("{...}", -1); + break; + + case TYPE_CODE_ARRAY: + { + char number[16]; + *obj = Tcl_NewStringObj (NULL, 0); + sprintf (number, "%d", var->num_children); + Tcl_AppendStringsToObj (*obj, "[", number, "]", NULL); + } + break; + + default: + result = call_gdb_val_print (val, format_code[(int) var->format]); + *obj = get_call_output (); + break; + } + + return result; +} + + +/* C++ */ + +static int +cplus_number_of_children (var) + gdb_variable *var; +{ + struct type *type; + int children, dont_know; + + dont_know = 1; + children = 0; + + if (!CPLUS_FAKE_CHILD (var)) + { + type = get_type_deref (var); + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + { + int kids[3]; + + cplus_class_num_children (type, kids); + if (kids[v_public] != 0) + children++; + if (kids[v_private] != 0) + children++; + if (kids[v_protected] != 0) + children++; + + /* Add any baseclasses */ + children += TYPE_N_BASECLASSES (type); + dont_know = 0; + + /* FIXME: save children in var */ + } + break; + } + } + else + { + int kids[3]; + + type = get_type_deref (var->parent); + + cplus_class_num_children (type, kids); + if (STREQ (var->name, "public")) + children = kids[v_public]; + else if (STREQ (var->name, "private")) + children = kids[v_private]; + else + children = kids[v_protected]; + dont_know = 0; + } + + if (dont_know) + children = c_number_of_children (var); + + return children; +} + +/* Compute # of public, private, and protected variables in this class. + That means we need to descend into all baseclasses and find out + how many are there, too. */ +static void +cplus_class_num_children (type, children) + struct type *type; + int children[3]; +{ + int i; + + children[v_public] = 0; + children[v_private] = 0; + children[v_protected] = 0; + + for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++) + { + /* If we have a virtual table pointer, omit it. */ + if (TYPE_VPTR_BASETYPE (type) == type + && TYPE_VPTR_FIELDNO (type) == i) + continue; + + if (TYPE_FIELD_PROTECTED (type, i)) + children[v_protected]++; + else if (TYPE_FIELD_PRIVATE (type, i)) + children[v_private]++; + else + children[v_public]++; + } +} + +static char * +cplus_name_of_child (parent, index) + gdb_variable *parent; + int index; +{ + char *name; + struct type *type; + int children[3]; + + if (CPLUS_FAKE_CHILD (parent)) + { + /* Looking for children of public, private, or protected. */ + type = get_type_deref (parent->parent); + } + else + type = get_type_deref (parent); + + name = NULL; + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + cplus_class_num_children (type, children); + + if (CPLUS_FAKE_CHILD (parent)) + { + /* FIXME: This assumes that type orders + inherited, public, private, protected */ + int i = index + TYPE_N_BASECLASSES (type); + if (STREQ (parent->name, "private") || STREQ (parent->name, "protected")) + i += children[v_public]; + if (STREQ (parent->name, "protected")) + i += children[v_private]; + + name = TYPE_FIELD_NAME (type, i); + } + else if (index < TYPE_N_BASECLASSES (type)) + name = TYPE_FIELD_NAME (type, index); + else + { + /* Everything beyond the baseclasses can + only be "public", "private", or "protected" */ + index -= TYPE_N_BASECLASSES (type); + switch (index) + { + case 0: + if (children[v_public] != 0) + { + name = "public"; + break; + } + case 1: + if (children[v_private] != 0) + { + name = "private"; + break; + } + case 2: + if (children[v_protected] != 0) + { + name = "protected"; + break; + } + default: + /* error! */ + break; + } + } + break; + + default: + break; + } + + if (name == NULL) + return c_name_of_child (parent, index); + else + { + if (name != NULL) + name = savestring (name, strlen (name)); + } + + return name; +} + +static value_ptr +cplus_value_of_root (var) + gdb_variable *var; +{ + return c_value_of_root (var); +} + +static value_ptr +cplus_value_of_child (parent, index) + gdb_variable *parent; + int index; +{ + struct type *type; + value_ptr value; + char *name; + gdb_result r; + + if (CPLUS_FAKE_CHILD (parent)) + type = get_type_deref (parent->parent); + else + type = get_type_deref (parent); + + value = NULL; + name = name_of_child (parent, index); + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + if (CPLUS_FAKE_CHILD (parent)) + { + value_ptr temp = parent->parent->value; + r = GDB_value_struct_elt (&temp, NULL, name, + NULL, "cplus_structure", &value); + if (r == GDB_OK) + release_value (value); + } + else if (index >= TYPE_N_BASECLASSES (type)) + { + /* public, private, or protected */ + return NULL; + } + else + { + /* Baseclass */ + if (parent->value != NULL) + { + value_ptr temp; + int i; + + if (TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_PTR + || TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_REF) + GDB_value_ind (parent->value, &temp); + else + temp = parent->value; + + r = GDB_value_cast (TYPE_FIELD_TYPE (type, index), temp, &value); + if (r == GDB_OK) + release_value (value); + } + } + break; + } + + if (value == NULL) + return c_value_of_child (parent, index); + + return value; +} + +static struct type * +cplus_type_of_child (parent, index) + gdb_variable *parent; + int index; +{ + struct type *type, *t; + gdb_result r; + + t = get_type_deref (parent); + type = NULL; + switch (TYPE_CODE (t)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + if (index >= TYPE_N_BASECLASSES (t)) + { + /* special */ + return NULL; + } + else + { + /* Baseclass */ + type = TYPE_FIELD_TYPE (t, index); + } + break; + + default: + break; + } + + if (type == NULL) + return c_type_of_child (parent, index); + + return type; +} + +static int +cplus_variable_editable (var) + gdb_variable *var; +{ + if (CPLUS_FAKE_CHILD (var)) + return 0; + + return c_variable_editable (var); +} + +static int +cplus_value_of_variable (var, obj) + gdb_variable *var; + Tcl_Obj **obj; +{ + + /* If we have one of our special types, don't print out + any value. */ + if (CPLUS_FAKE_CHILD (var)) + { + *obj = Tcl_NewStringObj ("", -1); + return TCL_OK; + } + + return c_value_of_variable (var, obj); +} + +/* Java */ + +static int +java_number_of_children (var) + gdb_variable *var; +{ + return cplus_number_of_children (var); +} + +static char * +java_name_of_child (parent, index) + gdb_variable *parent; + int index; +{ + char *name, *p; + + name = cplus_name_of_child (parent, index); + p = name; + + while (*p != '\000') + { + if (*p == '.') + *p = '-'; + p++; + } + + return name; +} + +static value_ptr +java_value_of_root (var) + gdb_variable *var; +{ + return cplus_value_of_root (var); +} + +static value_ptr +java_value_of_child (parent, index) + gdb_variable *parent; + int index; +{ + return cplus_value_of_child (parent, index); +} + +static struct type * +java_type_of_child (parent, index) + gdb_variable *parent; + int index; +{ + return cplus_type_of_child (parent, index); +} + +static int +java_variable_editable (var) + gdb_variable *var; +{ + return cplus_variable_editable (var); +} + +static int +java_value_of_variable (var, obj) + gdb_variable *var; + Tcl_Obj **obj; +{ + return cplus_value_of_variable (var, obj); +} + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/generic/gdbtk-varobj.c b/gdb/gdbtk/generic/gdbtk-varobj.c new file mode 100644 index 00000000000..2fadc73bfc4 --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk-varobj.c @@ -0,0 +1,633 @@ +/* Variable user interface layer for GDB, the GNU debugger. + Copyright 1999 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "value.h" + +#include "varobj.h" + +#include <tcl.h> +#include "gdbtk.h" + + +/* + * Public functions defined in this file + */ + +int gdb_variable_init PARAMS ((Tcl_Interp *)); + +/* + * Private functions defined in this file + */ + +/* Entries into this file */ + +static int gdb_variable_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); + +static int variable_obj_command PARAMS ((ClientData, Tcl_Interp *, int, + Tcl_Obj * CONST[])); + +/* Variable object subcommands */ + +static int variable_create PARAMS ((Tcl_Interp *, int, Tcl_Obj * CONST[])); + +static void variable_delete PARAMS ((Tcl_Interp *, struct varobj *, int)); + +static Tcl_Obj *variable_children PARAMS ((Tcl_Interp *, struct varobj *)); + +static int variable_format PARAMS ((Tcl_Interp *, int, Tcl_Obj * CONST[], + struct varobj *)); + +static int variable_type PARAMS ((Tcl_Interp *, int, Tcl_Obj * CONST[], + struct varobj *)); + +static int variable_value PARAMS ((Tcl_Interp *, int, Tcl_Obj * CONST[], + struct varobj *)); + +static Tcl_Obj *variable_update PARAMS ((Tcl_Interp * interp, struct varobj * var)); + +/* Helper functions for the above subcommands. */ + +static void install_variable PARAMS ((Tcl_Interp *, char *, struct varobj *)); + +static void uninstall_variable PARAMS ((Tcl_Interp *, char *)); + +/* String representations of gdb's format codes */ +char *format_string[] = +{"natural", "binary", "decimal", "hexadecimal", "octal"}; + +#if defined(FREEIF) +#undef FREEIF +#endif +#define FREEIF(x) if (x != NULL) free((char *) (x)) + +/* Initialize the variable code. This function should be called once + to install and initialize the variable code into the interpreter. */ +int +gdb_variable_init (interp) + Tcl_Interp *interp; +{ + Tcl_Command result; + static int initialized = 0; + + if (!initialized) + { + result = Tcl_CreateObjCommand (interp, "gdb_variable", call_wrapper, + (ClientData) gdb_variable_command, NULL); + if (result == NULL) + return TCL_ERROR; + + initialized = 1; + } + + return TCL_OK; +} + +/* This function defines the "gdb_variable" command which is used to + create variable objects. Its syntax includes: + + gdb_variable create + gdb_variable create NAME + gdb_variable create -expr EXPR + gdb_variable create -frame FRAME + (it will also include permutations of the above options) + + NAME = name of object to create. If no NAME, then automatically create + a name + EXPR = the gdb expression for which to create a variable. This will + be the most common usage. + FRAME = the frame defining the scope of the variable. + */ +static int +gdb_variable_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + static char *commands[] = + {"create", "list", NULL}; + enum commands_enum + { + VARIABLE_CREATE, VARIABLE_LIST + }; + int index, result; + + if (objc < 2) + { + Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0, + &index) != TCL_OK) + { + return TCL_ERROR; + } + + switch ((enum commands_enum) index) + { + case VARIABLE_CREATE: + result = variable_create (interp, objc - 2, objv + 2); + break; + + default: + return TCL_ERROR; + } + + return result; +} + +/* This function implements the actual object command for each + variable object that is created (and each of its children). + + Currently the following commands are implemented: + - delete delete this object and its children + - update update the variable and its children (root vars only) + - numChildren how many children does this object have + - children create the children and return a list of their objects + - name print out the name of this variable + - format query/set the display format of this variable + - type get the type of this variable + - value get/set the value of this variable + - editable is this variable editable? + */ +static int +variable_obj_command (clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + enum commands_enum + { + VARIABLE_DELETE, + VARIABLE_NUM_CHILDREN, + VARIABLE_CHILDREN, + VARIABLE_FORMAT, + VARIABLE_TYPE, + VARIABLE_VALUE, + VARIABLE_NAME, + VARIABLE_EDITABLE, + VARIABLE_UPDATE + }; + static char *commands[] = + { + "delete", + "numChildren", + "children", + "format", + "type", + "value", + "name", + "editable", + "update", + NULL + }; + struct varobj *var = (struct varobj *) clientData; + int index, result; + + if (objc < 2) + { + Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0, + &index) != TCL_OK) + return TCL_ERROR; + + result = TCL_OK; + switch ((enum commands_enum) index) + { + case VARIABLE_DELETE: + if (objc > 2) + { + int len; + char *s = Tcl_GetStringFromObj (objv[2], &len); + if (*s == 'c' && strncmp (s, "children", len) == 0) + { + variable_delete (interp, var, 1 /* only children */ ); + break; + } + } + variable_delete (interp, var, 0 /* var and children */ ); + break; + + case VARIABLE_NUM_CHILDREN: + Tcl_SetObjResult (interp, Tcl_NewIntObj (varobj_get_num_children (var))); + break; + + case VARIABLE_CHILDREN: + { + Tcl_Obj *children = variable_children (interp, var); + Tcl_SetObjResult (interp, children); + } + break; + + case VARIABLE_FORMAT: + result = variable_format (interp, objc, objv, var); + break; + + case VARIABLE_TYPE: + result = variable_type (interp, objc, objv, var); + break; + + case VARIABLE_VALUE: + result = variable_value (interp, objc, objv, var); + break; + + case VARIABLE_NAME: + { + char *name = varobj_get_expression (var); + Tcl_SetObjResult (interp, Tcl_NewStringObj (name, -1)); + FREEIF (name); + } + break; + + case VARIABLE_EDITABLE: + Tcl_SetObjResult (interp, Tcl_NewIntObj ( + varobj_get_attributes (var) & 0x00000001 /* Editable? */ )); + break; + + case VARIABLE_UPDATE: + /* Only root variables can be updated */ + { + Tcl_Obj *obj = variable_update (interp, var); + Tcl_SetObjResult (interp, obj); + } + break; + + default: + return TCL_ERROR; + } + + return result; +} + +/* + * Variable object construction/destruction + */ + +/* This function is responsible for processing the user's specifications + and constructing a variable object. */ +static int +variable_create (interp, objc, objv) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +{ + enum create_opts + { + CREATE_EXPR, CREATE_FRAME + }; + static char *create_options[] = + {"-expr", "-frame", NULL}; + struct varobj *var; + char *name; + char *obj_name; + int index; + CORE_ADDR frame = (CORE_ADDR) -1; + + /* REMINDER: This command may be invoked in the following ways: + gdb_variable create [NAME] [-expr EXPR] [-frame FRAME] + + NAME = name of object to create. If no NAME, then automatically create + a name + EXPR = the gdb expression for which to create a variable. This will + be the most common usage. + FRAME = the address of the frame defining the variable's scope + */ + name = NULL; + if (objc) + name = Tcl_GetStringFromObj (objv[0], NULL); + if (name == NULL || *name == '-') + { + /* generate a name for this object */ + obj_name = varobj_gen_name (); + } + else + { + /* specified name for object */ + obj_name = strdup (name); + objv++; + objc--; + } + + /* Run through all the possible options for this command */ + name = NULL; + while (objc > 0) + { + if (Tcl_GetIndexFromObj (interp, objv[0], create_options, "options", + 0, &index) != TCL_OK) + { + free (obj_name); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + return TCL_ERROR; + } + + switch ((enum create_opts) index) + { + case CREATE_EXPR: + name = Tcl_GetStringFromObj (objv[1], NULL); + objc--; + objv++; + break; + + case CREATE_FRAME: + { + char *str; + str = Tcl_GetStringFromObj (objv[1], NULL); + frame = parse_and_eval_address (str); + objc--; + objv++; + } + break; + + default: + break; + } + + objc--; + objv++; + } + + /* Create the variable */ + var = varobj_create (obj_name, name, frame); + + if (var != NULL) + { + /* Install a command into the interpreter that represents this + object */ + install_variable (interp, obj_name, var); + Tcl_SetObjResult (interp, Tcl_NewStringObj (obj_name, -1)); + result_ptr->flags |= GDBTK_IN_TCL_RESULT; + + free (obj_name); + return TCL_OK; + } + + free (obj_name); + return TCL_ERROR; +} + +/* Delete the variable object VAR and its children */ +/* If only_children_p, Delete only the children associated with the object. */ +static void +variable_delete (interp, var, only_children_p) + Tcl_Interp *interp; + struct varobj *var; + int only_children_p; +{ + char **dellist; + char **vc; + + varobj_delete (var, &dellist, only_children_p); + + vc = dellist; + while (*vc != NULL) + { + uninstall_variable (interp, *vc); + free (*vc); + vc++; + } + + FREEIF (dellist); +} + +/* Return a list of all the children of VAR, creating them if necessary. */ +static Tcl_Obj * +variable_children (interp, var) + Tcl_Interp *interp; + struct varobj *var; +{ + Tcl_Obj *list; + struct varobj **childlist; + struct varobj **vc; + char *childname; + + list = Tcl_NewListObj (0, NULL); + + varobj_list_children (var, &childlist); + + vc = childlist; + while (*vc != NULL) + { + childname = varobj_get_objname (*vc); + /* Add child to result list and install the Tcl command for it. */ + Tcl_ListObjAppendElement (NULL, list, + Tcl_NewStringObj (childname, -1)); + install_variable (interp, childname, *vc); + vc++; + } + + FREEIF (childlist); + return list; +} + +/* Update the values for a variable and its children. */ +/* NOTE: Only root variables can be updated... */ + +static Tcl_Obj * +variable_update (interp, var) + Tcl_Interp *interp; + struct varobj *var; +{ + Tcl_Obj *changed; + struct varobj **changelist; + struct varobj **vc; + + changed = Tcl_NewListObj (0, NULL); + + /* varobj_update() can return -1 if the variable is no longer around, + i.e. we stepped out of the frame in which a local existed. */ + if (varobj_update (var, &changelist) == -1) + return changed; + + vc = changelist; + while (*vc != NULL) + { + /* Add changed variable object to result list */ + Tcl_ListObjAppendElement (NULL, changed, + Tcl_NewStringObj (varobj_get_objname (*vc), -1)); + vc++; + } + + FREEIF (changelist); + return changed; +} + +/* This implements the format object command allowing + the querying or setting of the object's display format. */ +static int +variable_format (interp, objc, objv, var) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + struct varobj *var; +{ + if (objc > 2) + { + /* Set the format of VAR to given format */ + int len; + char *fmt = Tcl_GetStringFromObj (objv[2], &len); + if (STREQN (fmt, "natural", len)) + varobj_set_display_format (var, FORMAT_NATURAL); + else if (STREQN (fmt, "binary", len)) + varobj_set_display_format (var, FORMAT_BINARY); + else if (STREQN (fmt, "decimal", len)) + varobj_set_display_format (var, FORMAT_DECIMAL); + else if (STREQN (fmt, "hexadecimal", len)) + varobj_set_display_format (var, FORMAT_HEXADECIMAL); + else if (STREQN (fmt, "octal", len)) + varobj_set_display_format (var, FORMAT_OCTAL); + else + { + Tcl_Obj *obj = Tcl_NewStringObj (NULL, 0); + Tcl_AppendStringsToObj (obj, "unknown display format \"", + fmt, "\": must be: \"natural\", \"binary\"" + ", \"decimal\", \"hexadecimal\", or \"octal\"", NULL); + Tcl_SetObjResult (interp, obj); + return TCL_ERROR; + } + } + else + { + /* Report the current format */ + Tcl_Obj *fmt; + + /* FIXME: Use varobj_format_string[] instead */ + fmt = Tcl_NewStringObj ( + format_string[(int) varobj_get_display_format (var)], -1); + Tcl_SetObjResult (interp, fmt); + } + + return TCL_OK; +} + +/* This function implements the type object command, which returns the type of a + variable in the interpreter (or an error). */ +static int +variable_type (interp, objc, objv, var) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + struct varobj *var; +{ + char *first, *last, *string; + Tcl_RegExp regexp; + + /* For the "fake" variables, do not return a type. + Their type is NULL anyway */ + /* FIXME: varobj_get_type() calls type_print(), so we may have to wrap + its call here and return TCL_ERROR in the case it errors out */ + if ((string = varobj_get_type (var)) == NULL) + { + Tcl_ResetResult (interp); + return TCL_OK; + } + + first = string; + + /* gdb will print things out like "struct {...}" for anonymous structs. + In gui-land, we don't want the {...}, so we strip it here. */ + regexp = Tcl_RegExpCompile (interp, "{...}"); + if (Tcl_RegExpExec (interp, regexp, string, first)) + { + /* We have an anonymous struct/union/class/enum */ + Tcl_RegExpRange (regexp, 0, &first, &last); + if (*(first - 1) == ' ') + first--; + *first = '\0'; + } + + Tcl_SetObjResult (interp, Tcl_NewStringObj (string, -1)); + FREEIF (string); + return TCL_OK; +} + +/* This function implements the value object command, which allows an object's + value to be queried or set. */ +static int +variable_value (interp, objc, objv, var) + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; + struct varobj *var; +{ + char *r; + + /* If we're setting the value of the variable, objv[2] will contain the + variable's new value. */ + if (objc > 2) + { + /* FIXME: Do we need to test if val->error is set here? + If so, make it an attribute. */ + if (varobj_get_attributes (var) & 0x00000001 /* Editable? */ ) + { + char *s; + + s = Tcl_GetStringFromObj (objv[2], NULL); + if (!varobj_set_value (var, s)) + return TCL_ERROR; + } + + Tcl_ResetResult (interp); + return TCL_OK; + } + + r = varobj_get_value (var); + + if (r == NULL) + return TCL_ERROR; + else + { + Tcl_SetObjResult (interp, Tcl_NewStringObj (r, -1)); + FREEIF (r); + return TCL_OK; + } +} + +/* Helper functions for the above */ + +/* Install the given variable VAR into the tcl interpreter with + the object name NAME. */ +static void +install_variable (interp, name, var) + Tcl_Interp *interp; + char *name; + struct varobj *var; +{ + Tcl_CreateObjCommand (interp, name, variable_obj_command, + (ClientData) var, NULL); +} + +/* Unistall the object VAR in the tcl interpreter. */ +static void +uninstall_variable (interp, varname) + Tcl_Interp *interp; + char *varname; +{ + Tcl_DeleteCommand (interp, varname); +} + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/generic/gdbtk-wrapper.c b/gdb/gdbtk/generic/gdbtk-wrapper.c new file mode 100644 index 00000000000..b18825e6a6f --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk-wrapper.c @@ -0,0 +1,712 @@ +/* longjmp-free interface between gdb and gdbtk. + Copyright (C) 1999-2000 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" +#include "value.h" +#include "gdbtk-wrapper.h" + +/* + * Wrapper functions exported to the world + */ + +gdb_result GDB_value_fetch_lazy PARAMS ((value_ptr)); + +gdb_result GDB_evaluate_expression PARAMS ((struct expression *, value_ptr *)); + +gdb_result GDB_type_print (value_ptr, char *, struct ui_file *, int); + +gdb_result GDB_val_print (struct type * type, char *valaddr, + CORE_ADDR address, struct ui_file *stream, + int format, int deref_ref, int recurse, + enum val_prettyprint pretty); + +gdb_result GDB_select_frame PARAMS ((struct frame_info *, int)); + +gdb_result GDB_value_equal PARAMS ((value_ptr, value_ptr, int *)); + +gdb_result GDB_parse_exp_1 PARAMS ((char **stringptr, struct block * block, int comma, + struct expression ** result)); + +gdb_result GDB_evaluate_type PARAMS ((struct expression * exp, value_ptr * result)); + +gdb_result GDB_block_for_pc PARAMS ((CORE_ADDR pc, struct block ** result)); + +gdb_result GDB_block_innermost_frame PARAMS ((struct block * block, + struct frame_info ** result)); + +gdb_result GDB_reinit_frame_cache PARAMS ((void)); + +gdb_result GDB_find_frame_addr_in_frame_chain PARAMS ((CORE_ADDR addr, + struct frame_info ** result)); + +gdb_result GDB_value_ind PARAMS ((value_ptr val, value_ptr * rval)); + +gdb_result GDB_value_slice PARAMS ((value_ptr val, int low, int num, + value_ptr * rval)); + +gdb_result GDB_value_coerce_array PARAMS ((value_ptr val, value_ptr * rval)); + +gdb_result GDB_value_struct_elt PARAMS ((value_ptr * argp, value_ptr * args, + char *name, int *static_memfunc, + char *err, value_ptr * rval)); + +gdb_result GDB_value_cast PARAMS ((struct type * type, value_ptr val, value_ptr * rval)); + +gdb_result GDB_get_frame_block PARAMS ((struct frame_info * fi, struct block ** rval)); + +/* + * Private functions for this file + */ +static gdb_result call_wrapped_function PARAMS ((catch_errors_ftype *, + struct gdb_wrapper_arguments *)); + +static int wrap_type_print PARAMS ((char *)); + +static int wrap_evaluate_expression PARAMS ((char *)); + +static int wrap_value_fetch_lazy PARAMS ((char *)); + +static int wrap_val_print PARAMS ((char *)); + +static int wrap_select_frame PARAMS ((char *)); + +static int wrap_value_equal PARAMS ((char *)); + +static int wrap_parse_exp_1 PARAMS ((char *opaque_arg)); + +static int wrap_evaluate_type PARAMS ((char *opaque_arg)); + +static int wrap_block_for_pc PARAMS ((char *opaque_arg)); + +static int wrap_block_innermost_frame PARAMS ((char *opaque_arg)); + +static int wrap_reinit_frame_cache PARAMS ((char *opaque_arg)); + +static int wrap_find_frame_addr_in_frame_chain PARAMS ((char *opaque_arg)); + +static int wrap_value_ind PARAMS ((char *opaque_arg)); + +static int wrap_value_slice PARAMS ((char *opaque_arg)); + +static int wrap_value_coerce_array PARAMS ((char *opaque_arg)); + +static int wrap_value_struct_elt PARAMS ((char *opaque_arg)); + +static int wrap_value_cast PARAMS ((char *opaque_arg)); + +static int wrap_get_frame_block PARAMS ((char *opaque_arg)); + +static gdb_result +call_wrapped_function (fn, arg) + catch_errors_ftype *fn; + struct gdb_wrapper_arguments *arg; +{ + if (!catch_errors (fn, (char *) &arg, "", RETURN_MASK_ERROR)) + { + /* An error occurred */ + return GDB_ERROR; + } + + return GDB_OK; +} + +gdb_result +GDB_type_print (val, varstring, stream, show) + value_ptr val; + char *varstring; + struct ui_file *stream; + int show; +{ + struct gdb_wrapper_arguments args; + + args.args[0] = (char *) val; + args.args[1] = varstring; + args.args[2] = (char *) stream; + args.args[3] = (char *) show; + return call_wrapped_function ((catch_errors_ftype *) wrap_type_print, &args); +} + +static int +wrap_type_print (a) + char *a; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) a; + value_ptr val = (value_ptr) (*args)->args[0]; + char *varstring = (*args)->args[1]; + struct ui_file *stream = (struct ui_file *) (*args)->args[2]; + int show = (int) (*args)->args[3]; + type_print (VALUE_TYPE (val), varstring, stream, show); + return 1; +} + +gdb_result +GDB_val_print (type, valaddr, address, stream, format, deref_ref, + recurse, pretty) + struct type *type; + char *valaddr; + CORE_ADDR address; + struct ui_file *stream; + int format; + int deref_ref; + int recurse; + enum val_prettyprint pretty; +{ + struct gdb_wrapper_arguments args; + + args.args[0] = (char *) type; + args.args[1] = (char *) valaddr; + args.args[2] = (char *) &address; + args.args[3] = (char *) stream; + args.args[4] = (char *) format; + args.args[5] = (char *) deref_ref; + args.args[6] = (char *) recurse; + args.args[7] = (char *) pretty; + + return call_wrapped_function ((catch_errors_ftype *) wrap_val_print, &args); +} + +static int +wrap_val_print (a) + char *a; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) a; + struct type *type; + char *valaddr; + CORE_ADDR address; + struct ui_file *stream; + int format; + int deref_ref; + int recurse; + enum val_prettyprint pretty; + + type = (struct type *) (*args)->args[0]; + valaddr = (char *) (*args)->args[1]; + address = *(CORE_ADDR *) (*args)->args[2]; + stream = (struct ui_file *) (*args)->args[3]; + format = (int) (*args)->args[4]; + deref_ref = (int) (*args)->args[5]; + recurse = (int) (*args)->args[6]; + pretty = (enum val_prettyprint) (*args)->args[7]; + + val_print (type, valaddr, 0, address, stream, format, deref_ref, + recurse, pretty); + return 1; +} + +gdb_result +GDB_value_fetch_lazy (value) + value_ptr value; +{ + struct gdb_wrapper_arguments args; + + args.args[0] = (char *) value; + return call_wrapped_function ((catch_errors_ftype *) wrap_value_fetch_lazy, &args); +} + +static int +wrap_value_fetch_lazy (a) + char *a; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) a; + + value_fetch_lazy ((value_ptr) (*args)->args[0]); + return 1; +} + +gdb_result +GDB_evaluate_expression (exp, value) + struct expression *exp; + value_ptr *value; +{ + struct gdb_wrapper_arguments args; + gdb_result result; + args.args[0] = (char *) exp; + + result = call_wrapped_function ((catch_errors_ftype *) wrap_evaluate_expression, &args); + if (result != GDB_OK) + return result; + + *value = (value_ptr) args.result; + return GDB_OK; +} + +static int +wrap_evaluate_expression (a) + char *a; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) a; + + (*args)->result = + (char *) evaluate_expression ((struct expression *) (*args)->args[0]); + return 1; +} + +gdb_result +GDB_select_frame (fi, level) + struct frame_info *fi; + int level; +{ + struct gdb_wrapper_arguments args; + + args.args[0] = (char *) fi; + args.args[1] = (char *) &level; + + return call_wrapped_function ((catch_errors_ftype *) wrap_select_frame, &args); +} + +static int +wrap_select_frame (a) + char *a; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) a; + int level = *(int *) (*args)->args[1]; + struct frame_info *fi = (struct frame_info *) (*args)->args[0]; + + select_frame (fi, level); + return 1; +} + +gdb_result +GDB_value_equal (val1, val2, result) + value_ptr val1; + value_ptr val2; + int *result; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) val1; + args.args[1] = (char *) val2; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_value_equal, &args); + if (r != GDB_OK) + return r; + + *result = (int) args.result; + return GDB_OK; +} + +static int +wrap_value_equal (a) + char *a; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) a; + value_ptr val1, val2; + + val1 = (value_ptr) (*args)->args[0]; + val2 = (value_ptr) (*args)->args[1]; + + (*args)->result = (char *) value_equal (val1, val2); + return 1; +} + +gdb_result +GDB_parse_exp_1 (stringptr, block, comma, result) + char **stringptr; + struct block *block; + int comma; + struct expression **result; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) stringptr; + args.args[1] = (char *) block; + args.args[2] = (char *) comma; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_parse_exp_1, &args); + if (r != GDB_OK) + return r; + + *result = (struct expression *) args.result; + return GDB_OK; +} + +static int +wrap_parse_exp_1 (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + struct block *block; + char **stringptr; + int comma; + + stringptr = (char **) (*args)->args[0]; + block = (struct block *) (*args)->args[1]; + comma = (int) (*args)->args[2]; + + (*args)->result = (char *) parse_exp_1 (stringptr, block, comma); + return 1; +} + +gdb_result +GDB_evaluate_type (exp, result) + struct expression *exp; + value_ptr *result; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) exp; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_evaluate_type, &args); + if (r != GDB_OK) + return r; + + *result = (value_ptr) args.result; + return GDB_OK; +} + +static int +wrap_evaluate_type (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + struct expression *exp; + + exp = (struct expression *) (*args)->args[0]; + (*args)->result = (char *) evaluate_type (exp); + return 1; +} + +gdb_result +GDB_block_for_pc (pc, result) + CORE_ADDR pc; + struct block **result; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) &pc; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_block_for_pc, &args); + if (r != GDB_OK) + return r; + + *result = (struct block *) args.result; + return GDB_OK; +} + +static int +wrap_block_for_pc (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + CORE_ADDR pc; + + pc = *(CORE_ADDR *) (*args)->args[0]; + (*args)->result = (char *) block_for_pc (pc); + return 1; +} + +gdb_result +GDB_block_innermost_frame (block, result) + struct block *block; + struct frame_info **result; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) block; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_block_innermost_frame, &args); + if (r != GDB_OK) + return r; + + *result = (struct frame_info *) args.result; + return GDB_OK; +} + +static int +wrap_block_innermost_frame (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + struct block *block; + + block = (struct block *) (*args)->args[0]; + (*args)->result = (char *) block_innermost_frame (block); + return 1; +} + +gdb_result +GDB_reinit_frame_cache () +{ + gdb_result r; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_reinit_frame_cache, NULL); + if (r != GDB_OK) + return r; + + return GDB_OK; +} + +static int +wrap_reinit_frame_cache (opaque_arg) + char *opaque_arg; +{ + reinit_frame_cache (); + return 1; +} + +gdb_result +GDB_find_frame_addr_in_frame_chain (addr, result) + CORE_ADDR addr; + struct frame_info **result; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) &addr; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_find_frame_addr_in_frame_chain, &args); + if (r != GDB_OK) + return r; + + *result = (struct frame_info *) args.result; + return GDB_OK; +} + +static int +wrap_find_frame_addr_in_frame_chain (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + CORE_ADDR addr; + + addr = *(CORE_ADDR *) (*args)->args[0]; + (*args)->result = (char *) find_frame_addr_in_frame_chain (addr); + return 1; +} + +gdb_result +GDB_value_ind (val, rval) + value_ptr val; + value_ptr *rval; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) val; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_value_ind, &args); + if (r != GDB_OK) + return r; + + *rval = (value_ptr) args.result; + return GDB_OK; +} + +static int +wrap_value_ind (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + value_ptr val; + + val = (value_ptr) (*args)->args[0]; + (*args)->result = (char *) value_ind (val); + return 1; +} + +gdb_result +GDB_value_slice (val, low, num, rval) + value_ptr val; + int low; + int num; + value_ptr *rval; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) val; + args.args[1] = (char *) &low; + args.args[2] = (char *) # + + r = call_wrapped_function ((catch_errors_ftype *) wrap_value_slice, &args); + if (r != GDB_OK) + return r; + + *rval = (value_ptr) args.result; + return GDB_OK; +} + +static int +wrap_value_slice (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + value_ptr val; + int low, num; + + val = (value_ptr) (*args)->args[0]; + low = *(int *) (*args)->args[1]; + num = *(int *) (*args)->args[2]; + (*args)->result = (char *) value_slice (val, low, num); + return 1; +} + +gdb_result +GDB_value_coerce_array (val, rval) + value_ptr val; + value_ptr *rval; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) val; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_value_coerce_array, + &args); + if (r != GDB_OK) + return r; + + *rval = (value_ptr) args.result; + return GDB_OK; +} + +static int +wrap_value_coerce_array (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + value_ptr val; + + val = (value_ptr) (*args)->args[0]; + (*args)->result = (char *) value_coerce_array (val); + return 1; +} + +gdb_result +GDB_value_struct_elt (argp, args, name, static_memfunc, err, rval) + value_ptr *argp; + value_ptr *args; + char *name; + int *static_memfunc; + char *err; + value_ptr *rval; +{ + struct gdb_wrapper_arguments argss; + gdb_result r; + + argss.args[0] = (char *) argp; + argss.args[1] = (char *) args; + argss.args[2] = name; + argss.args[3] = (char *) static_memfunc; + argss.args[4] = err; + r = call_wrapped_function ((catch_errors_ftype *) wrap_value_struct_elt, &argss); + if (r != GDB_OK) + return r; + + *rval = (value_ptr) argss.result; + return GDB_OK; +} + +static int +wrap_value_struct_elt (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **argss = (struct gdb_wrapper_arguments **) opaque_arg; + value_ptr *argp, *args; + char *name; + int *static_memfunc; + char *err; + + argp = (value_ptr *) (*argss)->args[0]; + args = (value_ptr *) (*argss)->args[1]; + name = (*argss)->args[2]; + static_memfunc = (int *) (*argss)->args[3]; + err = (*argss)->args[4]; + + (*argss)->result = (char *) value_struct_elt (argp, args, name, static_memfunc, err); + return 1; +} + +gdb_result +GDB_value_cast (type, val, rval) + struct type *type; + value_ptr val; + value_ptr *rval; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) type; + args.args[1] = (char *) val; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_value_cast, &args); + if (r != GDB_OK) + return r; + + *rval = (value_ptr) args.result; + return GDB_OK; +} + +static int +wrap_value_cast (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + value_ptr val; + struct type *type; + + type = (struct type *) (*args)->args[0]; + val = (value_ptr) (*args)->args[1]; + (*args)->result = (char *) value_cast (type, val); + + return 1; +} + +gdb_result +GDB_get_frame_block (fi, rval) + struct frame_info *fi; + struct block **rval; +{ + struct gdb_wrapper_arguments args; + gdb_result r; + + args.args[0] = (char *) fi; + + r = call_wrapped_function ((catch_errors_ftype *) wrap_get_frame_block, &args); + if (r != GDB_OK) + return r; + + *rval = (struct block *) args.result; + return GDB_OK; +} + +static int +wrap_get_frame_block (opaque_arg) + char *opaque_arg; +{ + struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg; + struct frame_info *fi; + + fi = (struct frame_info *) (*args)->args[0]; + (*args)->result = (char *) get_frame_block (fi); + + return 1; +} + + + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/generic/gdbtk-wrapper.h b/gdb/gdbtk/generic/gdbtk-wrapper.h new file mode 100644 index 00000000000..e70a12c6303 --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk-wrapper.h @@ -0,0 +1,73 @@ +/* longjmp-free interface between gdb and gdbtk. + Copyright 1999-2000 Free Software Foundation, Inc. + +This file is part of GDB. It contains routines to safely call common gdb +functions without the fear of longjmp'ing. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef GDBTK_WRAPPER_H +#define GDBTK_WRAPPER_H +/* Use this struct used to pass arguments to wrapper routines. We assume + (arbitrarily) that no gdb function takes more than ten arguments. */ +struct gdb_wrapper_arguments { + + /* Pointer to some result from the gdb function call, if any */ + char *result; + + /* The list of arguments. */ + char *args[10]; +}; + +/* Whenever any gdb function wrapper is called, its return status is: */ +typedef enum gdb_wrapper_status { GDB_OK, GDB_ERROR } gdb_result; + +/* This list of functions which have been wrapped. Please keep this list + in alphabetical order, using "GDB_" to prefix the actual name of the + function. */ +extern gdb_result GDB_evaluate_expression PARAMS ((struct expression *expr, value_ptr *val)); +extern gdb_result GDB_select_frame PARAMS ((struct frame_info *fi, int level)); +extern gdb_result GDB_type_print (value_ptr val, char *varstring, + struct ui_file *stream, int show); +extern gdb_result GDB_val_print (struct type *type, char *valaddr, + CORE_ADDR address, struct ui_file *stream, + int format, int deref_ref, int recurse, + enum val_prettyprint pretty); +extern gdb_result GDB_value_fetch_lazy PARAMS ((value_ptr value)); +extern gdb_result GDB_value_equal PARAMS ((value_ptr val1, value_ptr val2, int *result)); +extern gdb_result GDB_parse_exp_1 PARAMS ((char **stringptr, struct block *block, int comma, + struct expression **result)); +extern gdb_result GDB_evaluate_type PARAMS ((struct expression *exp, value_ptr *result)); +extern gdb_result GDB_block_for_pc PARAMS ((CORE_ADDR pc, struct block **result)); +extern gdb_result GDB_block_innermost_frame PARAMS ((struct block *block, + struct frame_info **result)); +extern gdb_result GDB_reinit_frame_cache PARAMS ((void)); +extern gdb_result GDB_find_frame_addr_in_frame_chain PARAMS ((CORE_ADDR addr, + struct frame_info **result)); +extern gdb_result GDB_value_ind PARAMS ((value_ptr val, value_ptr *rval)); +extern gdb_result GDB_value_slice PARAMS ((value_ptr val, int low, int num, + value_ptr *rval)); +extern gdb_result GDB_value_coerce_array PARAMS ((value_ptr val, value_ptr *rval)); +extern gdb_result GDB_value_struct_elt PARAMS ((value_ptr *argp, value_ptr *args, + char *name, int *static_memfunc, + char *err, value_ptr *rval)); +extern gdb_result GDB_value_cast PARAMS ((struct type *type, value_ptr val, + value_ptr *rval)); +gdb_result GDB_get_frame_block PARAMS ((struct frame_info *fi, struct block **rval)); +#endif /* GDBTK_WRAPPER_H */ + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/generic/gdbtk.c b/gdb/gdbtk/generic/gdbtk.c new file mode 100644 index 00000000000..87c60737e0a --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk.c @@ -0,0 +1,657 @@ +/* Startup code for gdbtk. + Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "symtab.h" +#include "inferior.h" +#include "command.h" +#include "bfd.h" +#include "symfile.h" +#include "objfiles.h" +#include "target.h" +#include "gdbcore.h" +#include "tracepoint.h" +#include "demangle.h" +#include "version.h" +#include "tui/tui-file.h" + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + +#include <sys/stat.h> + +#include <tcl.h> +#include <tk.h> +#include <itcl.h> +#include <tix.h> +#include <itk.h> +#include "guitcl.h" +#include "gdbtk.h" + +#include <signal.h> +#include <fcntl.h> +#include "top.h" +#include <sys/ioctl.h> +#include "gdb_string.h" +#include "dis-asm.h" +#include <stdio.h> +#include "gdbcmd.h" + +#include "annotate.h" +#include <sys/time.h> + +#ifdef __CYGWIN32__ +#include <sys/cygwin.h> /* for cygwin32_attach_handle_to_fd */ +#endif + +extern void _initialize_gdbtk (void); + +#ifndef __CYGWIN32__ +/* For unix natives, we use a timer to periodically keep the gui alive. + See comments before x_event. */ +static sigset_t nullsigmask; +static struct sigaction act1, act2; +static struct itimerval it_on, it_off; + +static void x_event_wrapper PARAMS ((int)); +static void +x_event_wrapper (signo) + int signo; +{ + x_event (signo); +} +#endif + + /* + * These two variables control the interaction with an external editor. + * If enable_external_editor is set at startup, BEFORE Gdbtk_Init is run + * then the Tcl variable of the same name will be set, and a command will + * called external_editor_command will be invoked to call out to the + * external editor. We give a dummy version here to warn if it is not set. + */ +int enable_external_editor = 0; +char *external_editor_command = "tk_dialog .warn-external \\\n\ +\"No command is specified.\nUse --tclcommand <tcl/file> or --external-editor <cmd> to specify a new command\" 0 Ok"; + +extern int Tktable_Init PARAMS ((Tcl_Interp * interp)); + +static void gdbtk_init PARAMS ((char *)); + +void gdbtk_interactive PARAMS ((void)); + +static void cleanup_init PARAMS ((int)); + +static void tk_command PARAMS ((char *, int)); + +#ifndef __CYGWIN32__ +static int target_should_use_timer PARAMS ((struct target_ops * t)); +#endif + +int target_is_native PARAMS ((struct target_ops *t)); + +int gdbtk_test PARAMS ((char *)); + +/* Handle for TCL interpreter */ +Tcl_Interp *gdbtk_interp = NULL; + +#ifndef __CYGWIN32__ +static int gdbtk_timer_going = 0; +#endif + +/* linked variable used to tell tcl what the current thread is */ +int gdb_context = 0; + +/* This variable is true when the inferior is running. See note in + * gdbtk.h for details. + */ +int running_now; + +/* This variable holds the name of a Tcl file which should be sourced by the + interpreter when it goes idle at startup. Used with the testsuite. */ +static char *gdbtk_source_filename = NULL; + + +#ifndef _WIN32 + +/* Supply malloc calls for tcl/tk. We do not want to do this on + Windows, because Tcl_Alloc is probably in a DLL which will not call + the mmalloc routines. + We also don't need to do it for Tcl/Tk8.1, since we locally changed the + allocator to use malloc & free. */ + +#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 +char * +TclpAlloc (size) + unsigned int size; +{ + return xmalloc (size); +} + +char * +TclpRealloc (ptr, size) + char *ptr; + unsigned int size; +{ + return xrealloc (ptr, size); +} + +void +TclpFree (ptr) + char *ptr; +{ + free (ptr); +} +#endif /* TCL_VERSION == 8.0 */ + +#endif /* ! _WIN32 */ + +#ifdef _WIN32 + +/* On Windows, if we hold a file open, other programs can't write to + * it. In particular, we don't want to hold the executable open, + * because it will mean that people have to get out of the debugging + * session in order to remake their program. So we close it, although + * this will cost us if and when we need to reopen it. + */ + +void +close_bfds () +{ + struct objfile *o; + + ALL_OBJFILES (o) + { + if (o->obfd != NULL) + bfd_cache_close (o->obfd); + } + + if (exec_bfd != NULL) + bfd_cache_close (exec_bfd); +} + +#endif /* _WIN32 */ + + +/* TclDebug (const char *fmt, ...) works just like printf() but + * sends the output to the GDB TK debug window. + * Not for normal use; just a convenient tool for debugging + */ + +void +TclDebug (char level, const char *fmt,...) +{ + va_list args; + char buf[10000], *v[3], *merge, *priority; + + switch (level) + { + case 'W': + priority = "W"; + break; + case 'E': + priority = "E"; + break; + case 'X': + priority = "X"; + break; + default: + priority = "I"; + } + + va_start (args, fmt); + + v[0] = "dbug"; + v[1] = priority; + v[2] = buf; + + vsprintf (buf, fmt, args); + va_end (args); + + merge = Tcl_Merge (3, v); + if (Tcl_Eval (gdbtk_interp, merge) != TCL_OK) + Tcl_BackgroundError (gdbtk_interp); + Tcl_Free (merge); +} + + +/* + * The rest of this file contains the start-up, and event handling code for gdbtk. + */ + +/* + * This cleanup function is added to the cleanup list that surrounds the Tk + * main in gdbtk_init. It deletes the Tcl interpreter. + */ + +static void +cleanup_init (ignored) + int ignored; +{ + if (gdbtk_interp != NULL) + Tcl_DeleteInterp (gdbtk_interp); + gdbtk_interp = NULL; +} + +/* Come here during long calculations to check for GUI events. Usually invoked + via the QUIT macro. */ + +void +gdbtk_interactive () +{ + /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */ +} + +/* Start a timer which will keep the GUI alive while in target_wait. */ +void +gdbtk_start_timer () +{ +#ifndef __CYGWIN32__ + static int first = 1; + + if (first) + { + /* first time called, set up all the structs */ + first = 0; + sigemptyset (&nullsigmask); + + act1.sa_handler = x_event_wrapper; + act1.sa_mask = nullsigmask; + act1.sa_flags = 0; + + act2.sa_handler = SIG_IGN; + act2.sa_mask = nullsigmask; + act2.sa_flags = 0; + + it_on.it_interval.tv_sec = 0; + it_on.it_interval.tv_usec = 250000; /* .25 sec */ + it_on.it_value.tv_sec = 0; + it_on.it_value.tv_usec = 250000; + + it_off.it_interval.tv_sec = 0; + it_off.it_interval.tv_usec = 0; + it_off.it_value.tv_sec = 0; + it_off.it_value.tv_usec = 0; + } + + if (target_should_use_timer (¤t_target)) + { + if (!gdbtk_timer_going) + { + sigaction (SIGALRM, &act1, NULL); + setitimer (ITIMER_REAL, &it_on, NULL); + gdbtk_timer_going = 1; + } + } +#else /* __CYGWIN32__ */ + return; +#endif +} + +/* Stop the timer if it is running. */ +void +gdbtk_stop_timer () +{ +#ifndef __CYGWIN32__ + if (gdbtk_timer_going) + { + gdbtk_timer_going = 0; + setitimer (ITIMER_REAL, &it_off, NULL); + sigaction (SIGALRM, &act2, NULL); + } +#else /* __CYGWIN32__ */ + return; +#endif +} + +#ifndef __CYGWIN32__ +/* Should this target use the timer? See comments before + x_event for the logic behind all this. */ +static int +target_should_use_timer (t) + struct target_ops *t; +{ + return target_is_native (t); +} +#endif /* !__CYGWIN32__ */ + +/* Is T a native target? */ +int +target_is_native (t) + struct target_ops *t; +{ + char *name = t->to_shortname; + + if (STREQ (name, "exec") || STREQ (name, "hpux-threads") + || STREQ (name, "child") || STREQ (name, "procfs") + || STREQ (name, "solaris-threads") || STREQ (name, "linuxthreads")) + return 1; + + return 0; +} + +/* gdbtk_init installs this function as a final cleanup. */ + +static void +gdbtk_cleanup (dummy) + PTR dummy; +{ + Tcl_Eval (gdbtk_interp, "gdbtk_cleanup"); + Tcl_Finalize (); +} + +/* Initialize gdbtk. This involves creating a Tcl interpreter, + * defining all the Tcl commands that the GUI will use, pointing + * all the gdb "hooks" to the correct functions, + * and setting the Tcl auto loading environment so that we can find all + * the Tcl based library files. + */ + +static void +gdbtk_init (argv0) + char *argv0; +{ + struct cleanup *old_chain; + int found_main; + char s[5]; + Tcl_Obj *auto_path_elem, *auto_path_name; + + /* If there is no DISPLAY environment variable, Tk_Init below will fail, + causing gdb to abort. If instead we simply return here, gdb will + gracefully degrade to using the command line interface. */ + +#ifndef _WIN32 + if (getenv ("DISPLAY") == NULL) + return; +#endif + + old_chain = make_cleanup ((make_cleanup_func) cleanup_init, 0); + + /* First init tcl and tk. */ + Tcl_FindExecutable (argv0); + gdbtk_interp = Tcl_CreateInterp (); + +#ifdef TCL_MEM_DEBUG + Tcl_InitMemory (gdbtk_interp); +#endif + + if (!gdbtk_interp) + error ("Tcl_CreateInterp failed"); + + if (Tcl_Init (gdbtk_interp) != TCL_OK) + error ("Tcl_Init failed: %s", gdbtk_interp->result); + + /* Set up some globals used by gdb to pass info to gdbtk + for start up options and the like */ + sprintf (s, "%d", inhibit_gdbinit); + Tcl_SetVar2 (gdbtk_interp, "GDBStartup", "inhibit_prefs", s, TCL_GLOBAL_ONLY); + /* Note: Tcl_SetVar2() treats the value as read-only (making a + copy). Unfortunatly it does not mark the parameter as + ``const''. */ + Tcl_SetVar2 (gdbtk_interp, "GDBStartup", "host_name", (char*) host_name, TCL_GLOBAL_ONLY); + Tcl_SetVar2 (gdbtk_interp, "GDBStartup", "target_name", (char*) target_name, TCL_GLOBAL_ONLY); + + make_final_cleanup (gdbtk_cleanup, NULL); + + /* Initialize the Paths variable. */ + if (ide_initialize_paths (gdbtk_interp, "") != TCL_OK) + error ("ide_initialize_paths failed: %s", gdbtk_interp->result); + + if (Tk_Init (gdbtk_interp) != TCL_OK) + error ("Tk_Init failed: %s", gdbtk_interp->result); + + if (Itcl_Init (gdbtk_interp) == TCL_ERROR) + error ("Itcl_Init failed: %s", gdbtk_interp->result); + Tcl_StaticPackage (gdbtk_interp, "Itcl", Itcl_Init, + (Tcl_PackageInitProc *) NULL); + + if (Itk_Init (gdbtk_interp) == TCL_ERROR) + error ("Itk_Init failed: %s", gdbtk_interp->result); + Tcl_StaticPackage (gdbtk_interp, "Itk", Itk_Init, + (Tcl_PackageInitProc *) NULL); + + if (Tix_Init (gdbtk_interp) != TCL_OK) + error ("Tix_Init failed: %s", gdbtk_interp->result); + Tcl_StaticPackage (gdbtk_interp, "Tix", Tix_Init, + (Tcl_PackageInitProc *) NULL); + + if (Tktable_Init (gdbtk_interp) != TCL_OK) + error ("Tktable_Init failed: %s", gdbtk_interp->result); + + Tcl_StaticPackage (gdbtk_interp, "Tktable", Tktable_Init, + (Tcl_PackageInitProc *) NULL); + /* + * These are the commands to do some Windows Specific stuff... + */ + +#ifdef __CYGWIN32__ + if (ide_create_messagebox_command (gdbtk_interp) != TCL_OK) + error ("messagebox command initialization failed"); + /* On Windows, create a sizebox widget command */ + if (ide_create_sizebox_command (gdbtk_interp) != TCL_OK) + error ("sizebox creation failed"); + if (ide_create_winprint_command (gdbtk_interp) != TCL_OK) + error ("windows print code initialization failed"); + if (ide_create_win_grab_command (gdbtk_interp) != TCL_OK) + error ("grab support command initialization failed"); + /* Path conversion functions. */ + if (ide_create_cygwin_path_command (gdbtk_interp) != TCL_OK) + error ("cygwin path command initialization failed"); + if (ide_create_shell_execute_command (gdbtk_interp) != TCL_OK) + error ("cygwin shell execute command initialization failed"); +#else + /* for now, this testing function is Unix only */ + if (cyg_create_warp_pointer_command (gdbtk_interp) != TCL_OK) + error ("warp_pointer command initialization failed"); +#endif + + /* + * This adds all the Gdbtk commands. + */ + + if (Gdbtk_Init (gdbtk_interp) != TCL_OK) + { + error ("Gdbtk_Init failed: %s", gdbtk_interp->result); + } + + Tcl_StaticPackage (gdbtk_interp, "Gdbtk", Gdbtk_Init, NULL); + + /* This adds all the hooks that call up from the bowels of gdb + * back into Tcl-land... + */ + + gdbtk_add_hooks (); + + /* Add a back door to Tk from the gdb console... */ + + add_com ("tk", class_obscure, tk_command, + "Send a command directly into tk."); + + /* + * Set the variables for external editor: + */ + + Tcl_SetVar (gdbtk_interp, "enable_external_editor", + enable_external_editor ? "1" : "0", 0); + Tcl_SetVar (gdbtk_interp, "external_editor_command", + external_editor_command, 0); + + /* find the gdb tcl library and source main.tcl */ + + { +#ifdef NO_TCLPRO_DEBUGGER + static char script[] = "\ +proc gdbtk_find_main {} {\n\ + global Paths GDBTK_LIBRARY\n\ + rename gdbtk_find_main {}\n\ + tcl_findLibrary gdb 1.0 {} main.tcl GDBTK_LIBRARY GDBTK_LIBRARY gdbtk/library gdbtcl {}\n\ + set Paths(appdir) $GDBTK_LIBRARY\n\ +}\n\ +gdbtk_find_main"; +#else + static char script[] = "\ +proc gdbtk_find_main {} {\n\ + global Paths GDBTK_LIBRARY env\n\ + rename gdbtk_find_main {}\n\ + if {[info exists env(DEBUG_STUB)]} {\n\ + source $env(DEBUG_STUB)\n\ + debugger_init\n\ + set debug_startup 1\n\ + } else {\n\ + set debug_startup 0\n\ + }\n\ + tcl_findLibrary gdb 1.0 {} main.tcl GDBTK_LIBRARY GDBTK_LIBRARY gdbtk/library gdbtcl {} $debug_startup\n\ + set Paths(appdir) $GDBTK_LIBRARY\n\ +}\n\ +gdbtk_find_main"; +#endif /* NO_TCLPRO_DEBUGGER */ + + /* fputs_unfiltered_hook = NULL; *//* Force errors to stdout/stderr */ + + fputs_unfiltered_hook = gdbtk_fputs; + + if (Tcl_GlobalEval (gdbtk_interp, (char *) script) != TCL_OK) + { + char *msg; + + /* Force errorInfo to be set up propertly. */ + Tcl_AddErrorInfo (gdbtk_interp, ""); + + msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY); + + fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */ + +#ifdef _WIN32 + MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL); +#else + fputs_unfiltered (msg, gdb_stderr); +#endif + + error (""); + + } + } + + /* Now source in the filename provided by the --tclcommand option. + This is mostly used for the gdbtk testsuite... */ + + if (gdbtk_source_filename != NULL) + { + char *s = "after idle source "; + char *script = concat (s, gdbtk_source_filename, (char *) NULL); + Tcl_Eval (gdbtk_interp, script); + free (gdbtk_source_filename); + free (script); + } + + + discard_cleanups (old_chain); +} + +/* gdbtk_test is used in main.c to validate the -tclcommand option to + gdb, which sources in a file of tcl code after idle during the + startup procedure. */ + +int +gdbtk_test (filename) + char *filename; +{ + if (access (filename, R_OK) != 0) + return 0; + else + gdbtk_source_filename = xstrdup (filename); + return 1; +} + +/* Come here during initialize_all_files () */ + +void +_initialize_gdbtk () +{ + if (use_windows) + { + /* Tell the rest of the world that Gdbtk is now set up. */ + + init_ui_hook = gdbtk_init; +#ifdef __CYGWIN32__ + (void) FreeConsole (); +#endif + } +#ifdef __CYGWIN32__ + else + { + DWORD ft = GetFileType (GetStdHandle (STD_INPUT_HANDLE)); + + switch (ft) + { + case FILE_TYPE_DISK: + case FILE_TYPE_CHAR: + case FILE_TYPE_PIPE: + break; + default: + AllocConsole (); + cygwin32_attach_handle_to_fd ("/dev/conin", 0, + GetStdHandle (STD_INPUT_HANDLE), + 1, GENERIC_READ); + cygwin32_attach_handle_to_fd ("/dev/conout", 1, + GetStdHandle (STD_OUTPUT_HANDLE), + 0, GENERIC_WRITE); + cygwin32_attach_handle_to_fd ("/dev/conout", 2, + GetStdHandle (STD_ERROR_HANDLE), + 0, GENERIC_WRITE); + break; + } + } +#endif +} + +static void +tk_command (cmd, from_tty) + char *cmd; + int from_tty; +{ + int retval; + char *result; + struct cleanup *old_chain; + + /* Catch case of no argument, since this will make the tcl interpreter dump core. */ + if (cmd == NULL) + error_no_arg ("tcl command to interpret"); + + retval = Tcl_Eval (gdbtk_interp, cmd); + + result = xstrdup (gdbtk_interp->result); + + old_chain = make_cleanup (free, result); + + if (retval != TCL_OK) + error (result); + + printf_unfiltered ("%s\n", result); + + do_cleanups (old_chain); +} + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/generic/gdbtk.h b/gdb/gdbtk/generic/gdbtk.h new file mode 100644 index 00000000000..4ef0550ac69 --- /dev/null +++ b/gdb/gdbtk/generic/gdbtk.h @@ -0,0 +1,181 @@ +/* Tcl/Tk interface routines header file. + Copyright 1994-1998, 2000 Free Software Foundation, Inc. + + Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support. + + This file is part of GDB. It contains the public data that is shared between + the gdbtk startup code and the gdbtk commands. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef _WIN32 +#define GDBTK_PATH_SEP ";" +#else +#define GDBTK_PATH_SEP ":" +#endif + +/* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way + gdbtk wants to use it... */ +#ifdef __linux__ +#undef SIOCSPGRP +#endif + +/* + * These are the version numbers for GDBTK. There is a package require + * statement in main.tcl that checks the version. If you make an incompatible + * change to the gdb commands, or add any new commands, be sure to bump the + * version number both here and in main.tcl. This will save us the trouble of + * having a version of gdb find the wrong versions of the Tcl libraries. + */ + +#define GDBTK_MAJOR_VERSION "1" +#define GDBTK_MINOR_VERSION "0" +#define GDBTK_VERSION "1.0" + +/* + * These are variables that are needed in gdbtk commands. + */ + +/* This variable determines where memory used for disassembly is read from. + If > 0, then disassembly comes from the exec file rather than the + target (which might be at the other end of a slow serial link). If + == 0 then disassembly comes from target. If < 0 disassembly is + automatically switched to the target if it's an inferior process, + otherwise the exec file is used. It is defined in gdbtk.c */ + + +extern int disassemble_from_exec; + +/* This variable is true when the inferior is running. Although it's + possible to disable most input from widgets and thus prevent + attempts to do anything while the inferior is running, any commands + that get through - even a simple memory read - are Very Bad, and + may cause GDB to crash or behave strangely. So, this variable + provides an extra layer of defense. It is defined in gdbtk.c */ + +extern int running_now; + +/* These two control how the GUI behaves when tracing or loading + They are defined in gdbtk-cmds.c */ + +extern int No_Update; +extern int load_in_progress; + +/* This is the main gdbtk interpreter. It is defined and initialized + in gdbtk.c */ + +extern Tcl_Interp *gdbtk_interp; + +/* These two are lookup tables for elements of the breakpoint structure that + gdbtk knows by string name. They are defined in gdbtk-cmds.c */ + +extern char *bptypes[]; +extern char *bpdisp[]; + +/* + * This structure controls how the gdb output is fed into call_wrapper invoked + * commands. See the explanation of gdbtk_fputs in gdbtk_hooks.c for more details. + */ + +typedef struct gdbtk_result + { + Tcl_Obj *obj_ptr; /* This will eventually be copied over to the + Tcl result */ + int flags; /* Flag vector to control how the result is + used. */ + } +gdbtk_result; + +struct target_ops; + +/* These defines give the allowed values for the gdbtk_result.flags field. */ + +#define GDBTK_TO_RESULT 1 /* This controls whether output from + gdbtk_fputs goes to the command result, or + to gdbtk_tcl_fputs. */ +#define GDBTK_MAKES_LIST 2 /* whether gdbtk_fputs adds the + element it is outputting as a string, or + as a separate list element. */ +#define GDBTK_IN_TCL_RESULT 4 /* Indicates that the result is already in the + Tcl result. You can use this to preserve + error messages from functions like + Tcl_GetIntFromObj. You can also store the + output of a call wrapped command directly in + the Tcl result if you want, but beware, it will + not then be preserved across recursive + call_wrapper invocations. */ +#define GDBTK_ERROR_STARTED 8 /* This one is just used in gdbtk_fputs. If we + see some output on stderr, we need to clear + the result we have been accumulating, or the + error and the previous successful output + will get mixed, which would be confusing. */ +#define GDBTK_ERROR_ONLY 16 /* Indicates that all incoming I/O is + to be treated as if it had arrived for gdb_stderr. This is + used to help error_begin in utils.c. */ + +/* This is a pointer to the gdbtk_result struct that + we are currently filling. We use the C stack to make a stack of these + structures for nested calls to gdbtk commands that are invoked through + the call_wrapper mechanism. See that function for more details. */ + +extern gdbtk_result *result_ptr; + +/* GDB context identifier */ +extern int gdb_context; + +/* Internal flag used to tell callers of ui_loop_hook whether they should + detach from the target. See explanations before x_event and gdb_stop. */ +extern int gdbtk_force_detach; + +/* + * These functions are used in all the modules of Gdbtk. + * + */ + +extern int Gdbtk_Init (Tcl_Interp * interp); +extern void gdbtk_stop_timer PARAMS ((void)); +extern void gdbtk_start_timer PARAMS ((void)); +extern void gdbtk_ignorable_warning PARAMS ((const char *, const char *)); +extern void gdbtk_interactive PARAMS ((void)); +extern int x_event PARAMS ((int)); +extern int gdbtk_two_elem_cmd PARAMS ((char *, char *)); +extern int call_wrapper PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[])); +extern int target_is_native PARAMS ((struct target_ops *t)); +extern void gdbtk_fputs (const char *, struct ui_file *); + +#ifdef _WIN32 +extern void close_bfds (); +#endif /* _WIN32 */ + +extern void + TclDebug (char level, const char *fmt,...); + +/* A convenience macro for getting the demangled source names, + regardless of the user's mangling style. */ +#define GDBTK_SYMBOL_SOURCE_NAME(symbol) \ + (SYMBOL_DEMANGLED_NAME (symbol) != NULL \ + ? SYMBOL_DEMANGLED_NAME (symbol) \ + : SYMBOL_NAME (symbol)) + + +/* gdbtk_add_hooks - add all the hooks to gdb. This will get called + by the startup code to fill in the hooks needed by core gdb. */ +extern void gdbtk_add_hooks (void); + + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-gdbtk" */ +/* End: */ diff --git a/gdb/gdbtk/library/ChangeLog b/gdb/gdbtk/library/ChangeLog new file mode 100644 index 00000000000..8e0ae9e3b8b --- /dev/null +++ b/gdb/gdbtk/library/ChangeLog @@ -0,0 +1,6074 @@ +Fri Feb 4 23:19:03 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * gdb/gdbtcl2: Directory renamed to gdb/gdbtk/library. + +2000-01-12 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * targetselection.itb (init_target_db): Add the word "serial" to + the Angel target to make the distinction clear from the UDP connection. + +2000-01-05 Fernando Nasser <fnasser@totem.to.cygnus.com> + + From Dave Vogel (dave@lightsurf.com): + * targetselection.itb (init_target_db, config_dialog): Add support + for selecting a target running the Angel monitor (RDI protocol) + over an UDP connection. + * interface.tcl (set_target_name): Set hostname when target is RDI + over UDP (see previous entry). + +1999-12-15 Fernando Nasser <fnasser@rtl.cygnus.com> + + * variables.tcl: UnEdit any fields open to edit before colapsing + a tree branch (it was generating a Tcl exception and stack dump). + +1999-09-29 James Ingham <jingham@leda.cygnus.com> + + * prefs.tcl (pref_read): Convert env(HOME) to a win32 path BEFORE + handing it to file join, so we won't look for a network drive. + +1999-09-23 James Ingham <jingham@leda.cygnus.com> + + * toolbar.tcl (GDBToolBar): Typo. + (new_menu): Changed this to allow menus to be altered as well as + added. + (menu_exists): New method. + (clear_menu): New method. + (_load_src_images): Moved here from srcbar.tcl. Added Attach & + Detach classes. This is all still kind of ill-factored. + (In instance data): Made menu data arrays rather than dynamically + constructed variables. + + * srcwin.itb (SrcWin::set_execution_status): Let gdb print the PC, + since Tcl's conversion may not be wide enough. + + * srctextwin.ith: initialize the Cname variable. + + * srctextwin.itb (SrcTextWin::location): + (SrcTextWin::location): Change address compare to a string + compare. These are always both hex in the same format, but on a + 64 bit host the conversion would fail. + (SrcTextWin::showBalloon): Catch all errors in the balloon help + but also report them to the debug window. + (SrcTextWin::LoadFromCache): Erase and reload dirty cached windows. + + * srcbar.tcl (create_run_menu): Add "Attach", "Detach" and "Kill" + for native targets. + (do_attach): Attach to a native target. + (do_detach): Detach from a native target. + (do_kill): Kill a native target. + + * memwin.itb (MemWin::toggle_enabled): Toggle the state of the + widget, as well as the color, so people can't edit when the window + doesn't contain valid memory. + (MemWin::update_address): Set the state to normal if we have + loaded valid memory. + (MemWin::BadExpr): Set the state to disabled on error. + (MemWin::incr_addr): Set the state to normal if a step succeeds. + + * managedwin.itb (ManagedWin::open_dlg): New function. Preferred + function when you know you are opening a dialog. + (ManagedWin::_open): new function, contains the common bits of + opening windows & dialogs. + (ManagedWin::open): Use the _open function. + (ManagedWin::_create): Don't use Icon windows with modal dialogs. + + * interface.tcl (gdbtk_cleanup): Set a shutting_down flag. + (gdbtk_tcl_fputs): Restore the fputs hook. This is trivial to do, + and ensures that no one will delete the hook behind our backs. + (gdbtk_tcl_fputs_error): ditto. + (_open_file): Make file parameter optional, and don't query if it + is provided. + (gdbtk_attached): New function. Called from attach hook. + (gdbtk_detached): New function. Called from detach hook. + + * helpviewer.ith (HtmlViewer): Add the attach dialog to the list + of topics. + + * srcbar.tcl (do_kill): Added the Kill menu item for killing the + inferior on native targets. + +1999-09-16 James Ingham <jingham@leda.cygnus.com> + + * prefs.tcl (pref_set_defaults): define the wrap preference for + the console window. + + * console.itb (Console::_paste): Add the "delete selection" + semantics so we can use this for all the Paste events. + (Console::_delete): New method, centralize delete handling so we + can protect against things like delete deleting a selection up in + the history region of the window. + (Console::_build_win): Change bindings to use _paste & _delete. + (Console::_build_win): wrap if told to by the wrap parameter. + + * console.ith: Declare _delete. + +1999-09-16 Stan Shebs <shebs@andros.cygnus.com> + + * targetselection.itb (TargetSelection::init_target_db): Remove + references to D10V target, use only standard remote for D10V. + +1999-09-15 James Ingham <jingham@leda.cygnus.com> + + * console.itb (Console::_paste): Fix another "set foo [catch ...]" + idiom. + (Console::_build_win): Remove the extraneous posting of the + <<Paste>> event in handling B2-Release. Just call _paste. + +1999-09-10 James Ingham <jingham@leda.cygnus.com> + From Mumit Khan <khan@xraylith.wisc.edu> + + * prefs.tcl (pref_set_defaults): Add main_names preference. + * interface.tcl (gdbtk_locate_main): New proc. + (run_executable): Use. + * srcwin.itb (SrcWin::_build_win): Use. + (SrcWin::location): Likewise. + (SrcWin::point_to_main): Likewise. + +1999-08-27 James Ingham <jingham@leda.cygnus.com> + + * srctextwin.itb (SrcTextWin::FillAssembly): Use the new + gdb_load_disassembly. + (SrcTextWin::FillMixed): Use the new gdb_load_disassembly. + + * interface.tcl (gdbtk_idle): Call gdbtk_restore_fputs at idle + time. This puts the gdbtk_fputs hook back in place, just in case + an error left it pointing to null. + +1999-08-11 Tom Tromey <tromey@cygnus.com> + + * kod.itb (KodWin::build_win): Don't use Tix. + (Various): Changed as a result of build_win change. + (KodWin::destructor): Unset new globals. Also unset + kodActivePane. + + * kod.ith (labh): Removed variable. + + * kod.ith (set_os): Declare. + * kod.itb (KodWin::build_win): Don't use Tix labelled frame + widget or Tix paned widget. Removed size boxes from Windows + code. + (KodWin::constructor): Add `$this set' to gdb_set_hook. + (KodWin::destructor): Remove from hook. + (KodWin::set_os): New method. + + * toolbar.tcl (GDBToolBar::destructor): Remove from gdb_set_hook. + (GDBToolBar::constructor): Add to gdb_set_hook. + (set_hook): New method. + (create_view_menu): Don't put kod onto menu. + + * kod.itb (KodWin::display_object): Don't put `Details' message in + label; this messes up resize and doesn't really add anything. + + * images/kod.gif, images2/kod.gif: Removed. + * toolbar.tcl (create_window_buttons): Removed kod button. + (add_menu_command): Don't load kod image. + + * kod.itb: Renamed from kod.tcl. Restructured to follow new itcl + conventions. + * kod.ith: New file. + + * toolbar.tcl (create_window_buttons): Use gdb_kod_cmd, not + gdb_kod_name. + (create_view_menu): Likewise. + * interface.tcl (initialize_gdbtk): Don't mention gdb_kod_name. + + * targetselection.itb (TargetSelection::init_target_db): Added + Cisco targets. From Martin Hunt. + + * kod.tcl (build_win): Use correct capitalization for buttons. + +1999-08-10 James Ingham <jingham@leda.cygnus.com> + + * srctextwin.itb (SrcTextWin::constructor): Add the disassembly + flavor hook. + (SrcTextWin::disassembly_changed): New method, fix up all the + windows when the disassembly flavor changes. + (SrcTextWin::_mtime_changed): We were setting the filename:dirty + to 1 regardless of the result of the mtime check... Doh! + (SrcTextWin::reconfig): The setTabs call was assuming ALL windows + were source windows. + (SrcTextWin::do_tag_popup): Remove the balloon when the breakpoint + popups are posted as well. + (SrcTextWin::do_source_popup): Also handle the case where there is + a selection, but the point is not over it. + + * srctextwin.itb (SrcTextWin::destructor): Remove it when the + object goes away. + + * regwin.itb (RegWin::constructor): Add the disassembly_flavor_hook. + (RegWin::destructor): Remove it when the widget is destroyed. + (RegWin::disassembly_changed): New method, tell the widget it + needs to redisplay itself with the new register names. + (RegWin::reconfig): Actually do the reconstruction if the register + set names have changed. + * regwin.ith: Add declarations for the new methods. + + * interface.tcl (gdbtk_tcl_disassembly_hook): New hook to support + changing the disassembly flavor. + + * srctextwin.itb (SrcTextWin::getVariable): Use a selection in + preference to the word around the hit point, if there is one. + (SrcTextWin::do_source_popup): Really dismiss the balloon when you + popup a menu... + +1999-08-05 James Ingham <jingham@leda.cygnus.com> + + * srctextwin.itb (SrcTextWin::showBalloon): Fix ShowBalloon. We + can't use "info line" to tell us whether we should post a balloon + over the current line, since gdb only considers the first line of + a statement executible, not the continuation lines. Instead, show + any line in the currently selected function. Sigh... + +1999-08-06 Tom Tromey <tromey@cygnus.com> + + * interface.tcl (gdb_set_hook): New hook. + +1999-08-02 Tom Tromey <tromey@cygnus.com> + + * managedwin.ith (window_name): Removed extraneous comma. + +1999-07-27 Keith Seitz <keiths@cygnus.com> + + * variables.tcl: Rewrite to use new variable rewrite. + * locals.tcl: Ditto. + * watch.tcl: Ditto. + * srctextwin.itb (updateBalloon): Use new variable rewrite. + * blockframe.ith, blockframe.itb: New block and frame classes. + * data.ith, data,itb: New stack and queue classes (data structures). + * tclIndex: Rebuilt. + +1999-07-20 Jason Molenda (jsm@bugshack.cygnus.com) + + * prefs.tcl (pref_set_defaults): Set tab_size to the univeral + standard of 8, not 4. + +1999-07-16 Stan Shebs <shebs@andros.cygnus.com> + + * All files (*.tcl, *.itb, *.ith): Add GPL notices, regularize + copyright and header comments. + +1999-06-29 James Ingham <jingham@leda.cygnus.com> + + * bpwin.itb (BpWin::bp_store): New proc, store away the current + breakpoint list into a gdb command file. + (BpWin::bp_restore): restore a breakpoint list from a command file. + (BpWin::build_win): Add menu items for store & restore breakpoints. + +1999-06-24 Keith Seitz <keiths@cygnus.com> + + * srcwin.itb (SrcWin::destructor): Its "gdb_clear_file_hook", + not "gdb_clear_file". + +1999-06-23 James Ingham <jingham@leda.cygnus.com> + + * srctextwin.itb (SrcTextWin::_mtime_changed): Catch the call to + mtime. This will fail when you are in assembly mode, and the file + is actually a function address. + (SrcTextWin::motion): Catch the call to showBalloon. There are + various things that can go wrong here, and we certainly don't want + the user to hear about them. + +1999-06-15 Keith Seitz <keiths@cygnus.com> + + * interface.tcl (gdbtk_stop_idle_callback): Catch calls to + remove hook, since it could already be gone if we got a signal. + + * srcwin.itb (busy): If there is no target and the + debugger is native, we should also let the user know + that his program is running. + +1999-06-11 James Ingham <jingham@leda.cygnus.com> + + * interface.tcl (gdbtk_tcl_exec_file_display): Only call clear + file if there is a file loaded in the source window. This avoids + some flashing at startup. + +1999-06-10 Keith Seitz <keiths@cygnus.com> + + * srctextwin.itb (do_source_popup): Clear the varBalloon tag + before mapping a popup onto the screen. + (showBalloon): The "-pc" option was removed from gdb_variable. + Provide equivalent functionality, and display popups again. + + * interface.tcl (set_target): Don't call the target dialog + if there gdb_target_cmd is empty and we are a native debugger. + Don't set a default target -- force the gui to ask the first + time! + (run_executable): Set options after we have a target, not before. + + * watch.tcl (destructor): Don't call no_inferior -- the window's + already been destroyed. Instead, run through our list of variables + and delete them. + +1999-06-10 James Ingham <jingham@leda.cygnus.com> + + * srctextwin.itb (SrcTextWin::clear_file): Don't try to set the + text view back to the gdbtk_scratch_widget, this is very fragile. + (SrcTextWin::LoadFromCache): initialize the mtime correctly when + you add a window to the cache. + (SrcTextWin::LoadFromCache): don't add the ,asm,lib to the scratch + widget pane name. + + * interface.tcl (gdbtk_tcl_exec_file_display): Only run + gdbtk_clear_file if the filename is not null. This avoids source + window flashing. + + * srctextwin.itb (SrcTextWin::_mtime_changed): Set a dirty flag + when the mtime has changed so that you can know to reload the + source. + (SrcTextWin::LoadFromCache): Look at the dirty flag, and reload + from disk if it is set. + +1999-06-10 Keith Seitz <keiths@cygnus.com> + + * watch.tcl (clear_file): New method. + * variables.tcl (constructor): Register gdb_clear_file hook. + (destructor): Unregister gdb_clear_file hook. + (clear_file): New method. + * targetselection.itb (init_target_db): Add Picobug monitor. + (fill_targets): Don't explicitly list every TCP target: deduce + it from the target database. + (native_debugging): Compare host and target triples. + * srcwin.ith (clear_file): Add declaration. + * srcwin.itb (constructor): Register gdb_clear_file hook. + (destructor): Unregister gdb_clear_file hook. + (clear_file): New method. + * srctextwin.ith (LoadFile): Add arg "mtime_changed". + (clear_file): Add declaration. + (_mtime_changed): Add declaration. + (_initialize_srctextwin): Add declaration. + (_clear_cache): Add declaration. + * srctextwin.itb (constructor): Move all initialization + to _intialize_srctextwin so that we can easily re-initialize. + (Stwc): Change layout to explicitly list panes + and mtimes. + (ClearTags): Catch calls removing tags. Needed when + loading new executables. + (_mtime_changed): New method. + (FillSource): Immitate command line gdb, checking + if a file has changed since it was last used. If it has, load + it into the cache. + (LoadFile): Add parameter to inform whether a file's + mtime has changed. Reload the cache if it has. + (clear_file): New method. + (_initialize_srctextwin): New method. + (_clear_cache): New method. Stubbed. + * main.tcl: Move initialization of state to initialize_gdbtk in + interface.tcl + * interface.tcl (gdbtk_tcl_exec_file_display): Don't reset source + windows or globals here -- the clear file hook will do that. + (set_exe_name): Always say the exe has changed, in case + the user reloads the same exe (which he's recompiled). + (set_exe): Don't call gdb_clear_file. + (set_target): Return string result codes. + (clear_file_hook): New hook. + (gdbtk_clear_file): New proc. + (initialize_gdbtk): New proc. Moved initialization of + globals (yich) here from main.tcl + * download.itb (download_it): When running set_target, + use new string return codes. + + * interface.tcl (gdbtk_attach_target): New proc. Moved + contents of run_executable dealing with attaching to + a target here. + (run_executable): Use gdbtk_attach_target. + (connect): Remove and merge with gdbtk_attach_target. + * srcbar.tcl (do_connect): Use gdbtk_attach_target to + attach to the target. + + * tclIndex: Regenerate. + +1999-06-07 James Ingham <jingham@leda.cygnus.com> + + * memwin.ith (numbytes): Change the default to 0, which means + "depends on window size". This is really the useful value. + + * memwin.itb (MemWin::newsize): Move getting the rheight to AFTER + the update idletasks. Otherwise the bbox call will return "" when + the window is being constructed. + (MemWin::reconfig): Set rheight back to "" to force it to be + recomputed. Both font changes and switch to "depends on window + size" could invalidate this. + +1999-06-08 Keith Seitz <keiths@cygnus.com> + + * srcwin.itb (set_execution_status): Do not try to second + guess gdb_target_has_execution with gdb_running. Make + gdb_running follow it. We'll have to fix those targets + that do not set inferior_pid as they crawl out of the woodwork. + +1999-06-07 James Ingham <jingham@leda.cygnus.com> + + * prefs.tcl (pref_set_defaults): Set the initial height and with + of the browser to 0 so the packer & gridder can get this right on + systems with different fonts. Fixes CR 100619. + + * browserwin.itb (BrowserWin::_build_win): Don't set the height + and width of the file_box and func_box. This keeps them from + floating correctly when there is not stored default. + +1999-06-04 James Ingham <jingham@leda.cygnus.com> + + * regwin.itb (RegWin::acceptEdit): Call gdbtk_update after + changing the register value so that the locals and watch window + will get updated if any of these variables are in registers. Fixes + CR 100670. + +1999-05-25 Keith Seitz <keiths@cygnus.com> + + * variables.tcl (getLocals): Don't pass any args to + gdb_get_{locals, args} so that the currently selected frame is used. + (context_switch): New method. + * locals.tcl (getVariablesBlankPath): Don't catch call to getLocals. + getLocals will do it and return {} if an error occurs. + Always pass the frame of the variable to the variable backend, + assuming that the selected frame is the proper frame to use. + (update): Recognize context switches a little better. + + * variables.tcl (cursor): New method. + (enable_ui): Use "cursor". + (disable_ui): Ditto. + (no_inferior): Ditto. + (open): Change toplevel's cursor when opening variables. + +1999-05-03 Martin Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_help_menu): Open About window as transient. + + * main.tcl: Open About window as transient. + + * about.tcl (About): Set window title. + +1999-04-27 James Ingham <jingham@cygnus.com> + + * srcpref.itb (build_win): Pack the frame containing the + disassembly flavor chooser. Redid some of the other packing to + look a bit nicer too. + + * srcpref.itb (save): Call apply and then close rather than + duplicating the apply code. + +1999-04-26 James Ingham <jingham@cygnus.com> + + * modal.tcl (ModalDialog): Add the "expire" variable, and cancel + the dialog after the given time if set. + + * managedwin.ith (destructor): Use the new quit_if_last method to + decide whether to quit the app or not. This way you can manage + create a splash screen and not quit the app when you take it down. + (quit_if_last): Add default implementation - returns 1. + + * about.tcl (quit_if_last): Add the quit_if_last to the About box, + returning 0. + + * main.tcl: Added a line to open a splash screen, but commented it + out for devo. + +1999-04-22 Keith Seitz <keiths@cygnus.com> + + * targetselection.itb (port_list): ManagedWin has a proc named + "open". We really want the tcl command "::open" to open a port. + +1999-04-15 Martin Hunt <hunt@cygnus.com> + + * prefs.tcl (pref_set_defaults): New pref, gdb/use_icons. + This is set if Unix should use gdbtk_icon.gif as an icon. Some + window managers, such as olvwm, have problems with it. + * managedwin.itb (ManagedWin::_create): Don't create icon + for Unix, unless gdb/use_icons is set. + * globalpref.itb (GlobalPref::build_win): Add a checkbutton to set + pref gdb/use_icons. + + * managedwin.itb (ManagedWin::window_name): If iconname is + not specified, use window name. + (ManagedWin::_create): For Unix, call make_icon_window. + (ManagedWin::make_icon_window): New function. Makes a unix + icon. + + * main.tcl: Set initial target to "exec" if running in + test mode. + + * bpwin.itb (BpWin::constructor): Set icon name to "BPs". + * regwin.itb (BpWin::build_win): Set icon name to "Regs". + * srcwin.itb (SrcWin::_update_title): Set icon name to basename + of filename. + * variables.tcl (VariableWin::build_win): Set icon name to "Locals". + +1999-04-12 Keith Seitz <keiths@cygnus.com> + + * variables.tcl (populate): Update the value of the parent variable's + children before stuffing them into the window. This makes sure + that the value of the variable is always current. + +1999-04-09 James Ingham <jingham@cygnus.com> + + * memwin.itb (MemWin::incr_addr): Fix the increment-decrement + control. It would allow you to scroll into negative addresses, + which causes some simulators to crash. It would also increment + improperly in cases where the address value in hex corresponded to + a negative signed int. + +1999-04-07 Martin Hunt <hunt@cygnus.com> + + * interface.tcl (gdbtk_signal): Don't set gdb_running to 0. + +1999-04-06 Martin Hunt <hunt@cygnus.com> + + * targetselection.itb (TargetSelection::getname): Call init_target_db. + (TargetSelection::init_target_db): Add target mon2000. Set + most remote targets to default to downloading. Add new + baudrates for remote target. Other misc target fixes. + (save) Use "pref setd" in case pref is not created yet. + (TargetSelection::config_dialog): Gray out port number when + in exec mode. + + * targetselection.ith: Add public proc init_target_db. + + * srcwin.itb (SrcWin::set_execution_status): Don't print anything + if gdb_running is 0. + + * srctextwin.itb (SrcTextWin::motion): Show variable values + even when not debugging. Needed so users can examine values after + a segfault. + + * interface.tcl (set_target): If the target name is "", + use the default target name. + (run_executable): Set gdb_running correctly. Don't + allow downloading to "exec". + (gdbtk_signal): New function called from gdbtk_annotate_signal. + Sets gdb_running to 0 and pops up a dialog with the + signal name and description. + + * main.tcl: Set initial target name to "". Set gdb_target_changed + so a dialog will always be forced the first time. + + * download.itb (Download::download_it): Set gdb_loaded before + notifying src windows the download is done. Catch the notifications + in case the dialog has been closed. + + * console.itb (Console::destructor): Set gdbtk_state(console) + to "" instead of unsetting it. + +1999-04-02 James Ingham <jingham@cygnus.com> + + * memwin.itb (MemWin::build_win): Remove the -validate option from + the memory spinner. It was not appropriate, since you can type + expressions into the window. + +1999-04-02 Keith Seitz <keiths@cygnus.com> + + * tclIndex: Rebuilt. + * toolbar.tcl (create_control_buttons): Use SrcWin's + inferior method to centralize control of inferior state. + (create_control_buttons): Ditto. + (source): Move SrcBar's public variable "source" here, + so that the toolbar can use that info, too. + * srcwin.itb (SrcWin::inferior): New public method + to consildate inferior control and dispatch to proper + handlers. + * srcwin.ith (SrcWin::inferior): Add declaration. + * srctextwin.itb (SrcTextWin::do_key): Use parent SrcWin's inferior + method to handle inferior state changes (run, step, next, etc). + * interface.tcl: Add procs to centralize inferior control: + gdbtk_step, gdbtk_next, gdbtk_stepi, gdbtk_nexti, gdbtk_run, + gdbtk_continue, gdbtk_finish, gdbtk_stop. + New stop button code (see comments before gdbtk_stop): + (gdbtk_stop_idle_callback): Idle callback for stop button. + (gdbtk_detach): New proc to forcibly detach from target. + * main.tcl: Initialize data used by stop button. + * srcbar.tcl (create_run_menu): Call SrcWin's inferior + method with button commands. + (source): Move "source" to Toolbar class. + +1999-03-29 Keith Seitz <keiths@cygnus.com> + + * browserwin.itb (BrowserWin::do_all_bp): Fix quoting of break + command. + (BrowserWin::_toggle_bp): Ditto. + +1999-03-19 Keith Seitz <keiths@cygnus.com> + + * download.itb (Download::download_it): Configure SrcWin's toolbar, + too, to a downloading state. + * srcbar.tcl (runstop): Change states from numbers to + strings to avoid confusion. + (_set_runstop): Change states from numbers to strings to + avoid confusion. + * srcwin.ith (toolbar): New public method. + * srcwin.itb: Change all references of runstop to use new strings + introduced into GDBSrcBar::_set_runstop. + (SrcWin::toolbar): New public method to configure the state of the toolbar. + * tclIndex: Regenerate. + +1999-03-18 Martin Hunt <hunt@cygnus.com> + + * interface.tcl (set_target_name): Remove first argument. + If prompt is not set, still update gdb_target_cmd. + (set_target): Call set_target_name with prompt argument + set correctly. + (run_executable): Check for no exe name. Catch problems + with bad target names and prompt for new one. + + * main.tcl: Set target name from prefs. If it is "", + the set "gdb_target_changed" to force it to be changed + later. + + * prefs.tcl (pref_set_defaults): Don't set target default + to "exec". Leave the default unset. + + * srcbar.tcl (create_menu_items): Update args to + set_target_name. + +1999-03-18 Keith Seitz <keiths@cygnus.com> + + * prefs.tcl (pref_read): Change unix preference filename + to ".gdbtkinit". This bogosity has been around long enough. + +1999-03-16 Martin Hunt <hunt@cygnus.com> + + * managedwin.itb (ManagedWin::_create): When running under + testsuite, don't resize. + +1999-03-13 James Ingham <jingham@cygnus.com> + + * browserwin.itb (BrowserWin::search): If all the files are + selected in the file box, then don't pass the files argument. + This makes the function browser a little quicker. The main + slowdown, however, is sorting the resultant list. Maybe do this + in C to get this quicker? + + * memwin.itb (MemWin::edit): Comment out the line that reads back + in the newly set memory value. Because of the chain of calls, + on Windows this causes some evil race that results in GDBTk + filling all the visible cells with the new value. I don't + understand it yet, so this is just a temporary fix. + +1999-03-12 James Ingham <jingham@cygnus.com> + + * memwin.ith (MemWin): Add saved_addr to the class. This is where + we store the old address before we change addresses, so that we + can get back to a good state in case of errors. + + * memwin.itb (MemWin::update_addr): gdb_get_mem does not always + return an error code when it hits an error. Catch that here. + (MemWin::update_address): Store away the old address, so we can + restore it if there is an error. + (MemWin::BadExpr): Restore the saved address in case of errors. + + +1999-03-09 James Ingham <jingham@cygnus.com> + + * Rebuilt tclIndex. + +1999-03-08 James Ingham <jingham@cygnus.com> + + * srctextwin.itb (SrcTextWin::constructor): pc(funcname) was + changed to pc(func), but the initialization was not changed... + + * download.ith (dont_remember_size): Download window should not + remember its size. + + * interface.tcl (connect): Handle the case where set_target + returns 3... + + * debugwin.itb (DebugWinDOpts::build_win): Replace $this delete + with delete object $this. + * tfind_args.tcl (build_win): Ditto... + * helpviewer.itb (HtmlViewer::_buildwin): Ditto... + + * srcbar.tcl (GDBSrcBar): Reorder the Source & the page setup & + print menus... + +1999-03-04 Martin Hunt <hunt@cygnus.com> + + * download.ith: New file. + * download.itb: New file. Implements itcl3 class and replaces + download.tcl. + + * srcbar.tcl (create_menu_items): Call create_run_menu + without arguments. + (create_run_menu): Add Disconnect and Connect to Run menu + instead of file menu. Change download_it to Download::download_it. + + * srctextwin.itb (do_key): Change binding to call + Download::download_it. + + * debugwin.itb (DebugWinDOpts::build_win): Add ProcessWIn to list + of classes for filter. + + * interface.tcl (set_target): No need to set window title. + (run_executable): Change download_it to Download::download_it + +1999-03-04 James Ingham <jingham@cygnus.com> + + * modal.tcl (ModalDialog): Handle WM_DELETE_WINDOW by calling the + cancel method. Also set unpost_notification to different values + in unpost & the destructor, so if the object dies irregularly, you + know not to try to double destruct it. + +1999-03-03 James Ingham <jingham@cygnus.com> + + * warning.tcl (WarningDlg::constructor):Destroy with unpost. + + * util.tcl (get_disassembly_flavor, set_disassembly_flavor, + init_disassembly_flavor): Added these functions for the Intel P2 + disassembly flavors. + (list_element_strcmp): New function for lsort -command on lists. + + * tracedlg.tcl (TraceDlg): Change combobox callback to reflect new + after behavior. + + * targetselction.itb (TargetSelection::save): If the target + is not valid, tell the user rather than simple refusing to go + away. + Also move stuff around to isolate the instance dependant stuff as + much as possible + Also replace delete with unpost. + + * targetselection.ith (TargetSelection): Make as much of the + initialization stuff Class functions as possible. Then only + initialize it once. + + * srcwin.ith (_update_title): initialize need_files. + + * srcwin.itb (SrcWin::_build_win): I changed the combobox so it + ran its code in an idle handler, so we can take out all the after + idle... cruft here. + + * srctextwin.ith (SrcTextWin): Added textheight variable so you + can adjust the height of the text display. + + * srctextwin.itb (SrcTextWin::build_win): Don't hardcode the size + of the text window, set it with the textheight option instead. + Also replace childsite with "component text" wherever required. + + * srcpref.itb (SrcPref::build_win, set_flavor): Added the Intel + disassembly flavor combobox. Added set_flavor method to support + this. + * srcpref.ith: Added declaration for set_flavor, and + disassembly_flavor instance variable. + + * modal.tcl (ModalDialog::post, unpost): Added unpost method to + provide a more regular way to dismiss the dialogs. Just + destroying them was leading to funny destruction order bugs. + Added cancel method, which is what client code should call to + "force close" the dialog, so child classes can override, and do + some cleanup. + + * memwin.itb (MemWin::destructor): Call the cancel method of the + Preferences dialog (if it is posted) rather than just destroying + it. + + * mempref.itb (MemPref::ok): call unpost, since this is a modal + dialog. + + * managedwin.itb (ManagedWin::reveal): Used to be called raise. + Don't reuse Tcl or Tk commands unless there is a really good + reason to... + (ManagedWin::destroy_toplevel): renamed from delete, which + conflicts both with the Itcl1.5 delete method, and the Itcl3.0 + delete command... Also, don't use this as the way to destroy + ManagedWins, rather destroy the object and let the object take + care of removing its toplevel. + (ManagedWin::_create): Group all the windows with + . for WindowManagers that properly handle this. + (ManagedWin::_create): Use dont_remember_size + rather than the instance variable. Also, windows which don't + remember size are not necessarily transient. + (ManagedWin::_create): Only call post if the + ManagedWin also isa ModalDialog. It is clearer what is going on. + * managedwin.ith: Carry through the name changes. + + * main.tcl: call init_disassembly_flavor for Intel assembly + flavors. + + *main.tcl: Group . with . This is half of the work required to + play nice with WindowMaker. The other half waits till we can get + gdb to pass the command-line arguments to Tcl. + + * interface.tcl: Add file_changed_hook to the hooks. The browser + window watches this and refreshes the file box if it changes. + + * globalpref.ith (GlobalPref): This should be a modal dialog. + * globalpref.itb (GlobalPref::build_win): call update idletasks, + not update. Since we are calling update, there is no reason to + delay calling resize_font_item_height. + * globalpref.itb: Replace destroy toplevel with unpost. + + * debugwin.itb (DebugWin::build_win): Replace childsite with + "component text" + + * console.itb (Console::_build_win): Replace childsite with + "component text" + + * browserwin.itb: Rewritten pretty completely. + * prefs.tcl (pref_set_defaults): add the browser preferences. + + * prefs.tcl (pref_set_defaults): add the intel disassembly flavor + preference. + + * about.tcl (About): This should be a modal dialog. + +1999-03-02 James Ingham <jingham@cygnus.com> + + * globalpref.itb (GlobalPref::make_font_item): Don't do the + resize_font_item_height here, since an update can cause the resize + before all the windows are built. Delay to the end of build_win + instead. + +1999-02-24 James Ingham <jingham@cygnus.com> + + * toolbar.tcl (remove_button): Specify the row in the toolbar from + which you are removing the item. On Windows, there are two rows + in the standard toolbar... + +1999-02-22 Martin Hunt <hunt@cygnus.com> + + * warning.tcl (WarningDlg::constructor): Remove extra quote + that was causing loading of this module to fail. + + * managedwin.itb (ManagedWin::_create): If the pack fails + (for example because the warning dialog reliazed it should + ignore the warning) print a warning debug message and return. + Also, while testing, tell the window manager to position + the window without asking the user for the position. + +1999-02-18 Martin Hunt <hunt@cygnus.com> + + * srctextwin.itb (SrcTextWin::FillAssembly): As a last resort, + if the disassembly fails for some reason, switch to the scratch + pane and write in a message about not being able to disassemble. + +1999-02-18 Martin Hunt <hunt@cygnus.com> + + * helpviewer.ith (HtmlViewer): Add thread and function + browser windows to help index. + + * help/index.toc: Removed. + +1999-02-18 Martin Hunt <hunt@cygnus.com> + + * help/thread.html: New file. Thread window online help. + * help/index.html: Add thread.html, and alphabetize list. + * help/source.html: Add index for thread_bp. + +1999-02-17 Martin Hunt <hunt@cygnus.com> + + * globalpref.itb (GlobalPref::build_win): Add a checkbutton to + allow use of an internet browser to read help files. + + * prefs.tcl (pref_set_defaults): Add preference gdb/help/browser. + Default is to use builtin html help. + + * helpviewer.itb (HtmlViewer::open_help): New public proc. + Depending on preferences, opens help in external browser or + internal htmlviewer. + + * toolbar.tcl (create_help_menu): Use HtmlViewer::open_help. + +1999-02-17 Martin Hunt <hunt@cygnus.com> + + * managedwin.itb (ManagedWin::_create): Restore some lines that + were accidently checked in commented out. + +1999-02-17 Keith Seitz <keiths@cygnus.com> + + * help/index.html: Add function browser. + * help/browser.html: New help file. + +1999-02-12 Martin Hunt <hunt@cygnus.com> + + * managedwin.itb (ManagedWin::_create): If a window class defines a + public variable "nosize" the size will not be set, only the position. + * browserwin.ith (toggle_all_bp): Add public variable "nosize". + +1999-02-12 Martin Hunt <hunt@cygnus.com> + + * process.ith: New file. + * process.itb: New file. Converted process.tcl to new itcl class. + * process.tcl: Deleted. + + * warning.tcl (WarningDlg::constructor): Set the window name. + +1999-02-11 Martin Hunt <hunt@cygnus.com> + + * variables.tcl (editEntry): Check that $variable is not empty. + + * warning.tcl (WarningDlg::constructor): Put focus on the + "OK" button and bind it to <Return>. + + * watch.tcl (add): If the user attempts to add a non-existent + variable to the watch-window, display an ignorable warning. + + * interface.tcl (gdbtk_tcl_ignorable_warning): -transient + should not take an argument. + (set_target_name): Ditto. + * srcbar.tcl (create_menu_items): Ditto. + * memwin.itb (MemWin::create_prefs): Ditto. + * managedwin.itb (ManagedWin::_create): Ditto. + +1999-02-11 James Ingham <jingham@cygnus.com> + + Move the Intel disassembly mode changes into devo. + + * main.tcl: Init the disassembly flavor bits. + * prefs.tcl: Define disassembly-flavor + * srcpref.ith: Add current_disassembly_flavor instance variable + and set_flavor method. + * srcpref.itb (build_win): Add the disassembly_flavor combobox. + (apply): set the flavor, if applicable. + (set_flavor): New method. + * util.tcl: Add 3 new functions - get_disassembly_flavor, + list_disassembly_flavor and init_disassembly_flavor. + +1999-02-10 Martin Hunt <hunt@cygnus.com> + + * srcwin.itb, download.tcl, main.tcl, srcbar.tcl: Removed old + IDE stuff. + + * toolbar.tcl (create_help_menu): Updated Cygnus URL and + removed old IDE stuff. + (create_ide_buttons): Removed. + +1999-02-10 Martin Hunt <hunt@cygnus.com> + + * managedwin.itb (ManagedWin::_create): Bind Alt-F4 to + always close the window. + +1999-02-10 Martin Hunt <hunt@cygnus.com> + + * main.tcl: Removed old debugging preferences. + * prefs.tcl (pref_set_defaults): Ditto. + +1999-02-09 Martin Hunt <hunt@cygnus.com> + + * managedwin.itb (ManagedWin::_create): Simplify raise + and post now that all windows use new manager. + + * warning.tcl (WarningDlg): Rewrite of entire class to use + new itcl 3.0 class. Also now uses a "class name" to keep + track of which messages should be ignored. Uses tk_messageBox + of the message doesn't have -ignorable set. + + * interface.tcl: Removed IDE stuff. + (gdbtk_tcl_ignorable_warning): Accept "class" argument and + use it when creating a WarningDlg. Use new ManagedWin::open. + + * srctextwin.itb (SrcTextWin::set_tp_at_line): Fix TraceDlg + open command to use ManagedWin::open. + + * srcpref.itb (SrcPref::build_win): Comment out line number + option. It wasn't very useful and did not become effective + until GDBtk was restarted. + +1999-02-09 James Ingham <jingham@cygnus.com> + + * srctextwin.itb (build_win): Set the paned window background to + white so it looks better when you switch windows. + + * mempref.itb (build_win): Use the libgui combobox for the bytes per + line field. + + * mempref.itb: remove some global declarations that I missed when + I converted all the variables to instance data. + + * variables.tcl (change_value): Catch one more place where $this + was being passed as a window name. + + * TODO: Added some more items, and removed some that had been fixed. + +Mon Feb 8 12:27:16 1999 Keith Seitz <keiths@cygnus.com> + + * interface.tcl (set_target_name): Fix switch syntax + error and getd the options preference in case it's not set. + + +Thu Feb 4 11:55:43 1999 Keith Seitz <keiths@cygnus.com> + + * targetselection.itb (_init_db): Add MIPS target. + (fill_targets): Ditto. + +Thu Feb 4 07:56:12 1999 Keith Seitz <keiths@cygnus.com> + + * targetselection.itb: Set "TargetSelection::target_trace" + as the correct trace for gdb_loaded. + * targetselection.ith: Make "target_trace" a public proc. + +1999-02-03 Martin Hunt <hunt@cygnus.com> + + * help/console.html: Cleaned up and added history and editing + commands. + + * stackwin.itb (StackWin::build_win): Remove balloon help. + + * console.itb (Console::_search_history): New function. + Does a pattern match on history buffer. + (Console::_rsearch_history): New function. Does a pattern + match on history buffer in the reverse direction. + (Console::_build_win): Bind Control-Up, Control-Down, + Shift-Up, and Shift-Down to search history instead of mess + up the console window. Bind Control-o to break to disable it. + + * help/stack.html: Cleanup. + + * help/source.html: Add a bunch of missing quotation marks. + +1999-02-03 Martin Hunt <hunt@cygnus.com> + + * memwin.itb: Change from tixControl widget to iwidgets::spinint. + Fix problems with error dialogs. + +1999-02-02 Martin Hunt <hunt@cygnus.com> + + * srctextwin.itb (SrcTextWin::do_source_popup): Even after fixing the + obvious syntax errors in this function, it didn't work. So I + simplified the logic. Now it will attempt to use whatever is selected. + If multiple lines are selected and tracing is enabled, it will set + tracepoints, otherwise it will try to extract a variable name from single + lines only. + + * main.tcl: Only open debugwin if GDBTK_DEBUG > 1. + + * toolbar.tcl (create_view_menu): Only add "Debug WIndow" menu + item if GDBTK_DEBUG is set. + +1999-02-02 Martin Hunt <hunt@cygnus.com> + + * browserwin.itb (BrowserWin::_fill_source): Add lib argument + from gdb_loc to the call to $Source location. + (BrowserWin::_goto_func): Ditto. + +1999-02-01 James Ingham <jingham@cygnus.com> + + * browserwin.itb (BrowserWin::_fill_source): Add a null lib + argument to the call to $Source location. + +1999-02-01 Martin Hunt <hunt@cygnus.com> + + * prefs.tcl (pref_save): Change the list of sections back into + a list. + +1999-02-01 Martin Hunt <hunt@cygnus.com> + + * srctextwin.itb (SrcTextWin::FillMixed): Simplify line formatting. + (SrcTextWin::continue_to_here): Call gdb_set_bp with new type arg. + (SrcTextWin::set_bp_at_line): Call gdb_set_bp with new type arg. + Use "catch" command and display error if there is one. + +1999-02-01 Martin Hunt <hunt@cygnus.com> + + * srcwin.itb (SrcWin::goto_func): Dont attach filename if + there isn't a valid one. + +Fri Jan 29 20:01:30 1999 Fernando Nasser <fnasser@rtl.cygnus.com> + + * main.tcl: Restored kod code lost with merge + * prefs.tcl: Ditto. + * srctextwin.tcl: Ditto. + * toolbar.tcl: Ditto + * kod.tcl: Adapted to the new branch. + +1999-01-28 Martin Hunt <hunt@cygnus.com> + + * srcwin.itb (SrcWin::_build_win): Only call gdb_loc once. + (SrcWin::location): Update linespec for gdb_loc to include + the "lib" arg. + + * srctextwin.itb (SrcTextWin::LoadFromCache): Add "lib" + argument. This is used to create a unique cache key so + we don't confuse the disassembly of a function in a shared + lib with the disassembly of its trampoline. Also updated + UnLoadFromCache, LoadFIle, FillSource, FillMixed, and FillAssembly + to pass this argument around. + + * helpviewer.ith (HtmlViewer::constructor): Declare we have a + constructor. + (PageStack::constructor): Delete this declaration. + + * helpviewer.itb (HtmlViewer::constructor): initialize args before + calling _buildwin + + * main.tcl: Only open initial debug window if GDBTK_DEBUG + is set. + + * help/debug.html: Add help for GDBTK_DEBUG + +Wed Jan 27 07:18:05 1999 Keith Seitz <keiths@cygnus.com> + + * interface.tcl (gdbtk_pc_changed): Removed. + (gdbtk_register_changed): New procedure. + (gdbtk_memory_changed): New procedure. + +Mon Dec 21 14:12:14 1998 Keith Seitz <keiths@cygnus.com> + + * manage.tcl (manage_create): Set window geometry after window is + created. + + * prefs.tcl (pref_save): Save out preferences for memory window, too. + +Thu Dec 17 08:54:37 1998 Keith Seitz <keiths@cygnus.com> + + * browser.tcl (fill_source): Strip off any function args + which could arise from C++ function names. + (search): Be careful of C++ functions with spaces in the name + returned from gdb_search. + +Tue Dec 15 13:24:42 1998 Keith Seitz <keiths@cygnus.com> + + * prefs.tcl (escape_value, unescape_value): New procs to + escape equal signs in preference values. + (pref_read): Use unescape_value whenever prefs are read. + (pref_save): Use escape_value whenever prefs are saved.. + +Tue Dec 15 11:07:01 1998 Keith Seitz <keiths@cygnus.com> + + * process.tcl (build_win): Do not export the listbox's selection + as the X selection so that multiple listboxes can have selections + highlighted at the same time. + + * stack.tcl (build_win): Ditto. + +Mon Dec 14 15:53:38 1998 Keith Seitz <keiths@cygnus.com> + + * watch.tcl (update): Catch errors to getLocals, which could error + if no symbol table is loaded. + + * locals.tcl (update): Ditto. + +1998-11-17 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * kod.tcl: fix <Double-1> command spec for listbox. + +1998-11-13 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (bp): Pass "asm" argument to do_bp. + (do_bp): Use asm argument to determine whether to + check for multiple bps on the same src line. Remove + redundant "if" statement. + +1998-11-12 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (do_bp): Fix multiple assembly + breakpoints mapping to the same line number. + +Thu Nov 12 15:20:15 1998 Jim Ingham <jingham@cygnus.com> + + * console.tcl (complete): I added the ability to pass from_tty + from gdb_cmd to the underlying commands. Pass 1 when the + command is invoked from the console. + + * interface.tcl (gdbtk_tcl_tstart, gdbtk_tcl_tstop): Run the + src window's do_tstop method rather than manipulating the + widgets by hand. + + * src.tcl (build_win): Redo the packing so that the function + combobox doesn't push all the other combo-boxes off the screen + if it has a very long function name in it. + + * srcbar.tcl (do_tstop): Added a mode that just changes the + GUI, which can be called from console hooks. + + * srctextwin.tcl: Fixed some bugs I introduced in setting + breakpoints in the assembly & mixed mode windows. Dropped + the notion of joint breakpoint images for lines that have + breakpoints of two separate types. Too fragile. + Also added the "dont_change_appearance" flag, used in the + continue_to_here method to tell the GUI not to reflect the + temporary disabling of all the breakpoints. + + * toolbar.tcl (insert_buttons): Added a little more error-checking. + +Wed Nov 11 08:40:04 1998 Fernando Nasser <fnasser@cygnus.com> + + * kod.c: adjusted sizes and packing options of widgets + +1998-11-10 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * main.tcl: small fix to the kod code as requested by the maintainers + * kod.tcl: use show kod and info <kod cmd> as per spec + +Mon Nov 9 17:00:45 1998 Fernando Nasser <fnasser@cygnus.com> + + * kod.tcl: New file that implements the Kernel Object Display window + * Makefile: added kod.tcl + * main.tcl: test for kod support + * manage.tcl (manage_init): support for kod + * prefs.tcl (pref_save, pref_set_defaults): ibid + * scrtextwin.tcl (config_win, do_key): ibid + * toolbar.tcl (_load_images, create_window_buttons, + create_view_menu): ibid + * tclIndex: regen + +Mon Nov 9 12:09:48 1998 Michael Snyder <msnyder@cleaver.cygnus.com> + + * actiondlg.tcl: Customize the stack collect string to collect + the FP reg plus 64 words of stack mem. This will work for many + targets. As noted in earlier comment, we need a way to configure + this to the specific target. + +Wed Nov 4 12:41:42 1998 Jim Ingham <jingham@cygnus.com> + + * actiondlg.tcl: Get the stack collect string from an instance + variable. Need to implement some way to get this from the + target settings... + * global_pref.tcl (toggle_tracing_mode): Add & remove hooks + when you go in and out of tracing mode. Also reset the B1 + behavior when you leave tracing mode + * interface.tcl (gdbtk_tcl_trace_find_hook): Added the trace + find hook, so you can switch the GUI state when the tfind + command is used to enter & leave browse mode. + * srcbar.tcl (constructor, destructor trace_find_hook): Added + the trace_find_hook to the source toolbar, and added the + necessary hooks to handle it. + * srctextwin.tcl (trace_find_hook): Added a trace find hook to + the sourcebar as well. + * stack.tcl (update): protect against errors in gdb_stack. + Just return "NO STACK" if we couldn't get it. + * src_pref.tcl (constructor, cancel): Put all the saved prefs + in an array, on cancel, see if any have changed and only + rebuild the window if there have been changes. + +1998-11-03 Keith Seitz <keiths@cygnus.com> + + * target.tcl: Add ice target. + (GdbLoadPref): Add "after_attaching" preference. + (set_saved): Add "after_attaching" preference. + (write_saved): Add "after_attaching" preference. + (change_target): Add "after_attaching" preference. + (build_win): Add "after_attaching" entry to options + frame. + + * main.tcl (set_target_name): Add ice target. + (set_target): If an "after_attaching" preference exists, + run it. + +Mon Nov 2 13:24:10 1998 Jim Ingham <jingham@cygnus.com> + + * bp.tcl (update): The hook function was passing more + arguments than this function expected. + +Mon Nov 2 11:16:10 1998 Jim Ingham <jingham@cygnus.com> + + * toolbar.tcl: Added Tdump image. + +Fri Oct 30 17:36:05 1998 Jim Ingham <jingham@cygnus.com> + + * src.tcl (set_execution_status): Changed status messages, + tracing is not the same as async debugging... + +Fri Oct 30 17:06:31 1998 Jim Ingham <jingham@cygnus.com> + + * bp.tcl (bp_all): Only remove tracepoints in the tracepoint + window, and breakpoints in the breakpoint window. + +Fri Oct 30 11:22:23 1998 Jim Ingham <jingham@cygnus.com> + + * actiondlg.tcl: Added special tag "Collect Stack". This + still needs to get hooked into the target database to deal + with targets that need to do something special to collect the + stack. Also moved some repeated code into loops. + * main.tcl (source_file): Source in a file of gdb commands. + * srcbar.tcl (constructor): Added source file menu entry, and + made stack buttons belong to both the Trace & Control classes. + * srctextwin.tcl (constructor): One too many separators in the + trace trace popup menu. + * tclIndex: regenerated. + * tfind_args.tcl: Added "tfind frame" + * toolbar.tcl (create_button): Allow a button to belong to + more than one class. + * toolbar.tcl (enable_ui): Eliminate redundant code, and allow + a button to belong to more than one class. + * toolbar.tcl (create_trace_menu): Added save tracepoints & + Tfind frame menu items. + * tracedlg.tcl: Added deletion of actions, and fixed a + the whiile-stepping combobox callback for the new combobox. + * util.tcl (save_trace_commands): new proc. + +1998-10-29 Michael Snyder <msnyder@demo-laptop2.cygnus.com> + + * target.tcl: add /dev/cua0 for Linux. + +Tue Oct 27 13:46:03 1998 Jim Ingham <jingham@cygnus.com> + + * Many little bug fixes all over in order to get tracing to work + along with normal program control. + * toolbar.tcl: Rewrote much of the code here to put commonly + used code into functions, and clean up adding menus and + buttons. Added the ability to disable particular menu items, + not just whole menus. Added the ability to delete and insert + buttons on the fly. + * srcbar.tcl: Pushed the changes to toolbar.tcl into this file. + * srctextwin.tcl: Changed the code dealing with breakpoints + and tracepoints to use the text tags more consistently. Use + only one set of menus for the whole widget, rather than having + a separate set for the SRC+ASM case. Rewrote a lot of the + code to separate out the tracing & program control functions. + * interface.tcl (gdbtk_tcl_breakpoint): pass more information + to the scrtextwin when a breakpoint changes state, so it can + do the right thing without having to guess... + * tracedlg.tcl (build_win): get the packing right so the + window expands correctly. + * main.tcl: do_tstop -> tstop, do_tstart -> tstart to avoid + confusion with the methods in ScrBar.tcl. + * prefs.tcl: Added two new preferences B1_Behavior to control + whether B1 sets breakpoints or tracepoints. + * src_prefs.tcl: Put in support for the B1_Behavior. + * global_prefs.tcl: Put back tracing checkbox. + * tdump.tcl: Fixed an incorrect (1 rather than 1.0) text + widget line specification. + * tfind_args.tcl (build_win): Bind return in the entry to the + OK button. Clear the entry field if the Type has changed. + * utils.tcl: Added comments for the debug commands. + * watch.tcl (build_win): Flash the OK button before invoking it. + +Wed Oct 28 16:19:57 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl: Changed the _map cache to use + the variable Cname instead of the kludgy upvar alias. + +Mon Oct 26 21:08:54 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (motion): Show breakpoint balloons + even when not running. + (showBPBalloon): Check for null before displaying. + +Wed Oct 21 10:05:17 1998 Martin M. Hunt <hunt@cygnus.com> + + * images/kod.gif: Added temporary kernel object display icon. + +Wed Oct 14 17:30:07 PDT 1998 Jim Ingham <jingham@cygnus.com> + + * main.tcl (gdbtk_tcl_preloop): Fixed the code to set gdb_exe_name. + I seem to have dropped a variable... + * main.tcl (_open_file): Make the open file dialog truely + modal on windows. + +Wed Oct 14 14:29:17 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl: Change default runlist for remote + targets to download. + (build_win): Add user-defined list of functions for + initial breakpoints. + + * main.tcl (run_executable): Set user-defined initial + breakpoints. + + * prefs.tcl (pref_set_defaults): Define new prefs + gdb/load/bp_at_func and gdb/load/bp_func. These are + user-defined initial breakpoints. + +Sat Oct 10 00:21:44 1998 Martin M. Hunt <hunt@cygnus.com> + + * help/source.html: Add new images, add description of changes + to breakpoints and threads support. Fix typos. + + * help/memory.html: Cleanup and add new information. + + * help/breakpoint.html: Reformat. + + * help/images: Add a bunch of new GIFs. + +1998-10-08 Keith Seitz <keiths@cygnus.com> + + * main.tcl (run_executable): Do not call set_exe here, either. + (_open_file): Add some comments about using set_exe + here instead of in download_it and run_executable. Do not look + for main, either, since the file hooks will take care of that. + + * interface.tcl (gdbtk_tcl_pre_add_symbol): Do not reset the + source windows here -- only show the user what is going on. + (gdbtk_tcl_post_add_symbol): Force the source windows' file + comboboxes to refill, since adding a symbol file may actually + expand the debugger's view of the world. + (gdbtk_tcl_file_changed): New hook proc. Called by file_changed_hook + in symfile.c, this hook will cause the source window to point + to main/entry. gdbtk_tcl_exec_file_display actually sets up + gdbtk for this. + (gdbtk_tcl_exec_file_display): Renamed from + gdbtk_tcl_exec_file_changed for clarity. This hook is called + from exec_file_display_hook in exec_file_command. This function + sets up gdbtk to use a new executable, including resetting the + debugger's state and source window(s). See comments in this file + for more information. + + * download.tcl (download_it): Don't call set_exe here and + do not touch state variables gdb_target_changed -- run_executable + will do it. (In short, make download_it one step closer to only + doing the download!) + +1998-10-08 Keith Seitz <keiths@cygnus.com> + + * variables.tcl (UnEdit): Fix quoting problems so that arrays may be + inspected/edited. + (edit): Ditto. + +Wed Oct 7 16:03:00 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (reconfig): Fix bindings. + +Wed Oct 7 13:07:00 1998 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_create): Bind ALL source windows + Map and Unmap events. + (manage_delete): Small optimization. + (manage_iconify): When the last source window is iconified, + iconify all the support windows too. When any source + window is deiconified, deiconify everything. + + * src.tcl (destructor): Destroy SrcTextWin too. + +Tue Oct 6 23:00:08 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (set_status): Display only the first line of + the message. + (build_win): Configure status window to a height of 1. + + * srcbar.tcl (create_menu_items): Change "Open..." + menu item to call _open_file proc. Remove old + _open_file method. + + * main.tcl (run_executable): If the run command fails + with a result of "No executable" then call _open_file. + (_open_file): New proc. Opens a file requester and + sets the executable name to the selected file. + + * toolbar.tcl (create_menu_items): Add "..." to Source + and Global prefs menu item. + +Mon Oct 5 21:10:30 1998 Jim Ingham <jingham@cygnus.com> + + * srctextwin.tcl (set_tracepoint): The filename variable + changed to current(filename) but this use was not updated. + + * global_prefs: Added a global preference to turn on the + tracing. It only sets the tracing preference, and does + not cause gdb to relayout the toolbar yet... + + * util.tcl: Fixed the comments for the little debug + thingie. + + * util.tcl (auto_step): Added a way to cancel the + auto_stepping. This is not currently used, but with this + it could be... + +Mon Oct 5 00:43:11 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (SrcTextWin): Create a threaded image + with a color of [pref get gdb/src/thread_fg]. + (bind_src_tags): Bind bp_tag <Motion> and <Leave> for + balloon help on breakpoints. + (config_win): A bunch of binding changes to support + balloon help breakpoints and setting multiple BPs + on a line. Add menu item for thread specific BPs. + (reconfig): Similar changes as above. + (register_balloon): Remove. + (updateBalloon): Cleanup and don't call register_balloon. + (do_bp): When a BP is deleted, call gdb_find_bp_at_line() + to see if there are any more BPs at the same line number. + Add "thread" BP type. + (bp_line): Accept an optional list of thread numbers to + set BPs on. Loop through the list setting BPs on each thread. + (motion): Accept a window and type argument. Call + showBPBalloon in type is not "var". + (showBPBalloon): New method.Opens a balloon with breakpoint + info in it. + (showballoon): Accept window parameter. + (ask_thread_bp): New. A thread selector dialog. Opens + a scrolled listbox with a list of threads and allows + the user to multiselect threads to set BPs on. + (do_thread_bp): New callback from ask_thread_bp() + listbox. + + * src_pref.tcl: Replace disabled color selector with thread + fg selector. Disabled color should probably always be + black anyways. + + * util.tcl (CygScrolledListbox): Temporary simple scrolled + listbox. Replace with a better one soon. + + * prefs.tcl (pref_set_defaults): Set default for thread fg. + + * bp.tcl (bp_add): For thread BPs, set the button color + correctly. + + * tclIndex: Rebuilt. + +Fri Oct 2 17:07:32 1998 Jim Ingham <jingham@cygnus.com> + + * util.tcl (debug namespace): Added helper functions + "trace_var", "remove_trace" & "remove_all_traces" which + watch a variable, and dump the stack, and its value when + it is touched... They are in the "debug" namespace. + *tclIndex: regenerate index. + +Fri Oct 2 14:02:25 1998 Jim Ingham <jingham@cygnus.com> + + * main.tcl (gdbtk_tcl_preloop): Catch the error when no file + is given on the command line. + +1998-10-02 Keith Seitz <keiths@cygnus.com> + + * srcbar.tcl (_open_file): Call SrcWin::point_to_main. + (_set_runstop): Catch the stop in case the user + aborts a session. + + * srctextwin.tcl (destructor): New. Remove all previously added + hooks. + + * src.tcl (point_to_main): New function. I got tired of typing + the same five lines over and over again. + + * main.tcl (set_baud): Target baud preferences are stored as + [target name]-baud, not [target name]/baud. + (run_executable): Call SrcWin::point_to_main. + (gdbtk_tcl_preloop): Call SrcWin::point_to_main. + + * interface.tcl (gdbtk_tcl_pre_add_symbol): Use "update idletasks", not + just "update". + (gdbtk_tcl_post_add_symbol): Rewrite to have better behavior + for symbol files which have been loaded. Use a small hack to work + with gdbtk_tcl_exec_file_changed so that we look for main only + when a new executable is loaded. + (gdbtk_tcl_exec_file_changed): New proc to do some necessary + setup when an exec file changes. + + * tclIndex: Regenerate. + +Fri Oct 2 11:40:05 1998 Martin M. Hunt <hunt@cygnus.com> + + * Makefile (TCL): Add modal.tcl. + + * tclIndex: Rebuilt. + +1998-10-02 Keith Seitz <keiths@cygnus.com> + + * srcbar.tcl (_set_runstop): Catch the stop in case the user + aborts a session. + +Thu Oct 1 18:58:11 1998 Jim Ingham <jingham@cygnus.com> + + * main.tcl (gdbtk_tcl_preloop): We were using lindex on the + return value from info files, but if the directory had a space + in it, then the result was not a proper Tcl list, and so the + command would fail. Use regexp instead... + +Thu Oct 1 17:21:26 1998 Jim Ingham <jingham@cygnus.com> + + * download.tcl (download_it): One more place where we used + "Foundry_Debugger" unconditionally... Stamped out. + + * main.tcl (set_target): Don't put the "Trying to + communicate..." message in the window title, put it in the + status area, and remember to remove it when you are done. + +Wed Sep 30 21:32:39 1998 Jim Ingham <jingham@cygnus.com> + + * srctextwin.tcl (insertBreakTag): There was a bug in the + method of inserting break tags. If a tag of the intended + type did not already exist, insertBreakTag would not set it. + This method is a little less flexible, but actually works + for all our uses. + +Wed Sep 30 19:42:43 1998 Jim Ingham <jingham@cygnus.com> + + * src.tcl (set_execution_status): When the program has + terminated, most stubs detach. Then we need to set + gdb_target_changed here so gdb will know to reattack when + you press the Run button. + + * memory.tcl (update_address): We caught the gdb_eval when you + give an address expression, but then only trapped the case + where you gave an invalid address or non-existant symbol. + Trap all the other errors as well... + +Wed Sep 30 16:55:53 1998 Martin M. Hunt <hunt@cygnus.com> + + * bp.tcl: Add optional "thread" column and menu items + to turn it on and off. + + * prefs.tcl (pref_set_defaults): Add gdb/bp/show_threads + preference used for toggling the display of the thread + column in the BP window. Default is 0 (off). + +1998-09-28 Keith Seitz <keiths@cygnus.com> + + * download.tcl (download_it): Don't download if there is no executable... + +Mon Sep 28 14:23:39 1998 Jim Ingham <jingham@cygnus.com> + + * modal.tcl: NEW FILE. Had to fix a bug in the dialogs + so I made a sub-class: ModalDialog. The bug was that + manage.tcl sets the WM_DELETE_WINDOW handler to be + "manage delete" of the window, which is wrong for these + windows, they need to unpost themselves first. Override + this in the post method. + * mem_pref.tcl: Subclass & remove the code that went into + the ModalDialog class. + * target.tcl: ditto. + * tclIndex: regenerate for the new class. + +Fri Sep 25 19:01:32 1998 Jim Ingham <jingham@cygnus.com> + + * utils.tcl (freeze): Hacked the freeze method so that it comes closer + to working on Windows, but it still flashes. Use a post + method, like that im mem_prefs.tcl or target.tcl instead. + * mem_pref.tcl (post): Added post method, so you can use the + Windows EnableWindow call without sending your app into the + background when the dialog is dismissed. + * target.tcl (post): Added the same method to this class. + Really should subclass these. Will do this when we rework the + class hierarchy for Itcl3.0. + * memory.tcl (create_prefs): Use the new post method. + * main.tcl (set_target_name): Use the post method rather than + freeze. + +1998-09-25 Keith Seitz <keiths@cygnus.com> + * main.tcl (set_baud): Baud rates are saved in gdb/load/target-baud, + not gdb/load/target/baud. + (set_target): Attempt to silently detach before attaching. + + * target.tcl: Add gdb_target entries for Angel and ARM Remote + protocols. + +1998-09-18 Keith Seitz <keiths@cygnus.com> + + * interface.tcl (gdbtk_tcl_post_add_symbol): Force the source window + to 'main'; if that fails, let gdb guess based on stop_pc. + +1998-09-04 Keith Seitz <keiths@cygnus.com> + + * srctextwin.tcl (SrcTextWin::destructor): Define and remove + previously installed hooks. + + * browser.tcl (get_selection): Listbox indices start at zero! + Clear the selection if the user clicks below the last visible + item in the listbox. + +Thu Sep 3 16:43:43 1998 Jim Ingham <jingham@leda.cygnus.com> + + * mem_prefs.tcl: Fixed the size & format radiogroups in + the memory preferences so that they match the format + options being sent to it by the memory window. Also + greyed out the format box when float or double is selected. + Also made sure we didn't re-enable any disabled widgets in + the idle function. + +Sun Aug 30 00:40:28 1998 Martin M. Hunt <hunt@cygnus.com> + + * process.tcl: New file. Implement a process/thread selection + and display window. + + * srctextwin.tcl (do_key): Add entry for thread/process + window. + (config_win): Bind "Thread List" to Control-H. + (FillSource): Fix bug when source is not found. + + * toolbar.tcl (create_menu_items): Add Thread List to menu + + * manage.tcl (manage_init): Add process window to + managed array. + + * prefs.tcl (pref_save): Add "process" to window types to save. + + * Makefile: Add process.tcl + + * tclIndex: Rebuilt + +1998-08-28 Keith Seitz <keiths@cygnus.com> + + * variables.tcl (edit): Format data so that C arrays are not + mistaken for tcl commands. + (UnEdit): Ditto. + +Thu Aug 27 14:13:09 1998 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (run_executable): If the target is "sim" + then the pref "sim-opts" should be treated as target + options instead of command line arguments. + +Wed Aug 26 00:06:11 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (mode): Set the mode widget using entryset. + (build_win): Use default combobox selectbackground. + + * srctextwin.tcl (FillMixed): Better error handling. + (LoadFIle): Stop harrassing users with worthless dialog boxes. + + * main.tcl (run_executable): Set args when arguments are + given in the target dialog. + + * helpViewer.tcl (insertHtml): Window may have been + closed while waiting for HTMLparse, so catch next commands + to prevent error message. + + * images/stack.gif: Use the image from images2 because + it looks better. + +Tue Aug 25 16:09:02 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (build_win): Change fonts on comboboxes to src-font. + + * global_pref.tcl: Change to new combobox. + +Tue Aug 25 11:41:43 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (insertBreakTag): Take an index + instead of a linenumber. Check for bp_tag and break_tag. + (display_breaks): Reset all lines back to break_tag + after deleting bp image. Fixes caching bug. + (do_bp): Fix up calls to insertBreakTag. + +Fri Aug 21 12:44:25 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl (build_win): Remove tix stuff. Set maxheight + of comboboxes to 10. Remove all code to count elements + in comboboxes because the new one does it for us. + (fill_rates): Remove combobox height configure code. + (fill_targets): Same. + + * src.tcl (build_win): Change combobox -height to + -maxheight for combobox 1.05. + (name, goto_func): Use combobox entryset instead of SetSilent. + (SetSilent): Deleted. + + * srctextwin.tcl (FillSource): Fix change mode call when + no source is found. + +1998-08-20 Keith Seitz <keiths@cygnus.com> + + * srctextwin.tcl (print): New method. Moved from src.tcl. + + * srcbar.tcl (create_menu_items): Add page setup for non-ide again.. + + * src.tcl (build_win): Fix balloon help for new comboboxes. + (print): Move guts to srctextwin and invoke that method. + + * target.tcl: Remove protected variable tcpmode. + Add "options" member for sim and exec targets. For sim, this is + options to pass to the simulator; for exec, command line arguments. + (build_win): Replace tix comboboxes with one from libgui. + (set_saved): Add target-options when appropriate. + (write_saved): Add target-options when appropriate. + (fill_rates): Modify to work with new combobox. + (fill_targets): Modify to work with new combobox. + (config_dialog): New method which maps/unmaps/relabels comboboxes + and entries for each target. + (change_target): Remove all code pertaining to mapping/unmapping/relabeling + comboboxes and entries and call config_dialog instead. + (change_baud): Remove all code pertaining to mapping/unmapping/relabeling + comboboxes and entries and call config_dialog instead. + + * console.tcl (Console): Add key binding for TAB completion. + (find_lcp): New helper method for find_completion. + (find_completion): New helper method for complete. + (complete): New method (bound to tab key) which computes the completion + of the current command line. + (reset_tab): New method to reset the tab completion whenever a key + is pressed (forces complete to recompute the completions instead of + printing out the last list of completions). + +1998-08-18 Keith Seitz <keiths@cygnus.com> + + * stack.tcl (update): Use new built-in command gdb_stack for + backtraces. + Use the global gdb_selected_frame_level to figure out which + line in the listbox should be highlighted. + ALWAYS highlight the selected frame. + Put a fencepost arount update so that we can prevent it from + being called twice when change_frame is used. + (change_frame): Protect call to gdbtk_update so that this object is + not updated twice. + + * srctextwin.tcl (config_win): Copy the properties of the selection tag + into a new "search" tag that will be used by the search widget. + (search): Use the defined "search" tag to highlight found text. + Remove all search-tagged text from the window when an empty expression + is entered. + +Mon Aug 17 14:27:54 1998 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (do_tstop): Require combobox package. + + * src.tcl (build_win): Use new combobox. + (name): Changes for new combobox. + (goto_func): Changes for new combobox. + (FillNameCB): Changes for new combobox. + (FillFuncCB): Changes for new combobox. + (SetSilent): New method, like tixSetSilent. + (mode): Changes for new combobox. + (set_name): Changes for new combobox. + (reset): Changes for new combobox. + + * srctextwin.tcl (FillSource): Call parent's mode method when + mode is changed to assembly. + (location): Call display_breaks only if flag is set. + (LoadFIle, FillAssembly, FillMixed): Set display_breaks flag. + (display_breaks): Set all breakpoints in a single pass. + (insertBreakTag): Check $stop before trying to remove tag. + +Mon Jul 27 12:35:31 1998 Martin M. Hunt <hunt@cygnus.com> + + * interface.tcl (gdbtk_tcl_tracepoint): Make function match C + implementation by adding pass_count. + +Sat Jul 25 22:40:49 1998 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_init): Change "loadpref" to "targetsel" + and change class name to TargetSelection. This avoids confusion + with the IDE GdbLoadPref class. + * target.tcl (TargetSelection): Change class name. + * main.tcl (set_target_name): Change "loadpref" to" targetsel" + +Fri Jul 24 14:37:49 1998 Keith Seitz <keiths@cygnus.com> + + * util.tcl (bp_exists): New procedure. + * srctextwin.tcl (SrcTextWin::constructor): Add public vars + "parent" and "ignore_var_balloons" and initialize accordingly. + (config_win): Add binding for browser. + Add binding for up/down arrows to scroll more naturally. + (do_key): Add browser entry. + * browser.tcl: Add srctextwin into browser. + * prefs.tcl (pref_set_defaults): Add new preferences for the func + browser. + * tclIndex: Regenerate. + +Fri Jul 24 00:53:28 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (SrcTextWin): Initialize LineNums. + (setTabs): Set tabs correctly when in assembly mode + or when there are no linenumbers. + (bind_src_tags): Remove lineNum_tag bindings. + (config_win): Remove lineNum_tag and line_tag. Set + linenumbers to break_tag and bp_tag instead. + (FillAssembly): Don't use lineNum_tag. + (FillMixed): Don't use line_tag. + (LoadFile): Use new protected variable LineNums. + (insertBreakTag): Instead of trying to calculate the + correct location of the new tag, simply ask the widget + where the old one was. + (do_bp): Call insertBreakTag when bps are deleted. + + * src.tcl (FillNameCB): Call gdb_listfiles with [pwd]. + +Sat Jul 18 13:27:20 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (location): Change BROWSE_TAG to STACK_TAG. + + * interface.tcl (gdbtk_quit): New function. Called by + cleanup code in GDB. + +Fri Jul 17 00:03:43 1998 Martin M. Hunt <hunt@cygnus.com> + + * memory.tcl (build_win): Change address controlbox to + call update_address_cb. + (update_address_cb): New method. Handle address + controlbox callbacks. Set flag and call update_address. + (update_address): Call BadExpr on bad expressions. + Use local variable "ae" to set public variable addr_exp. + This fixes bug where widget forgets its address when + reconfigured. Set table background white when expression + is OK. + (BadExpr): When a bad expression is entered, create a + messagebox and set the table bg to gray. + + * mem_pref.tcl (apply): Remove mystery debug line. + +Thu Jul 16 16:56:12 1998 Jim Ingham <jingham@cygnus.com> + + * download.tcl, ide.tcl, interface.tcl, main.tcl, manage.tcl + srcbar.tcl, toolbar.tcl: Merged the IDE changes back into devo. + +Mon Jul 13 14:34:45 1998 Jim Ingham <jingham@cygnus.com> + + * mem_pref.tcl (destructor): Remember to delete the variable + trace that implements the entry widget checking. + +Fri Jul 10 19:17:53 1998 Jim Ingham <jingham@cygnus.com> + + * mem_pref.tcl: Changed the number of bytes entry widget so + that it only accepts +'ve integers, and protect against the + case where the user deletes the contents of this entry, then + closes the window. Also made the entry disabled when the + other radio button is selected. + +Wed Jul 8 23:20:33 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (FillSource): Fix code that + detects when no line numbers are available and we must use + assembly mode. + +Mon Jul 6 17:53:50 1998 Jim Ingham <jingham@cygnus.com> + + * download.tcl, helpViewer.tcl, html_library.tcl, memory.tcl, + register.tcl, src.tcl, srctextwin.tcl, target.tcl, + tracedlg.tcl, util.tcl, variables.tcl, warning.tcl, watch.tcl: + With the Tcl 8.0 compiler, expr commands are more efficient if + you use: + expr {$foo + $bar} + instead of: + expr $foo + $bar + So I changed all the uses of expr to this form. + + +Mon Jul 6 15:19:59 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (FillSource): Call Parent's mode method + to combobox will be updated. + * src.tcl (mode): Pass along second argument to mode_set. + +Wed Jul 1 15:09:47 1998 Martin M. Hunt <hunt@cygnus.com> + + * srctextwin.tcl (location): Add missing parameter + to FillSource call in SRC+ASM. + +Wed Jul 1 11:07:21 1998 Jim Ingham <jingham@cygnus.com> + + * main.tcl (gdbtk_preloop): Call gdbtk_idle on spec. If there was an + error in loading an executible specified on the command line, + then the pre_add_symbol hook would have called gdbtk_busy but + the corresponding call to gdbtk_idle would not have occured. + + Also changed some catch calls so they didn't use + "catch {set foo [real_command]}" + but rather the more efficient: + "catch {real_command} foo" + + * register.tcl: more catch cleanups + * src.tcl: more catch cleanups + * stack.tcl: more catch cleanups + * target.tcl: more catch cleanups + * tdump.tcl: more catch cleanups + * variables.tcl: more catch cleanups + * watch.tcl: more catch cleanups + +Wed Jul 1 12:21:55 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (build_win): Remove incorrect runstop + argument for srcbar. + +Wed Jul 1 11:25:48 1998 Martin M. Hunt <hunt@cygnus.com> + + * floatbar.tcl: Deleted. + * Makefile: Removed floatbar.tcl + * tclIndex: Rebuilt. + +Wed Jul 1 11:19:05 1998 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (enable_ui): Now takes an argument and + handles disable_ui and no_inferior functions. + (disable_ui): Deleted. + (no_inferior): Deleted. + (constructor): Set idle, busy, and no_inferior hooks + to enable_ui. + + * srcbar.tcl (_open_file): Fix for multiple source windows. + +Wed Jul 1 01:40:52 1998 Martin M. Hunt <hunt@cygnus.com> + * Makefile: Added srctextwin.tcl. + * tclIndex: Rebuilt. + * src.tcl: Major rewrite to move the source text window + into another object implemented in srctextwin.tcl. Every function + changed and many moved to srctextwin.tcl. + * srctextwin.tcl: New file. + * bp.tcl (goto_bp): Fix call to source widget. + + * src_pref.tcl (build_win): Add line number + checkbutton. Layout needs changed. + * prefs.tcl (pref_set_defaults): Add linenum pref. + +Thu Jun 25 17:31:30 1998 Keith Seitz <keiths@cygnus.com> + + * toolbar.tcl (create_menu_items): Add Function Browser menu item. + + * tclIndex: Regenerate. + + * Makefile: Add browser.tcl. + + * util.tcl (do_test): New procedure for invoking a test in the + testsuite from the command line. + (gdbtk_read_defs): New procedure for reading in the testsuite definitions + file + + * src.tcl (build_win): Create new entry for searching the source window. + This "feature" shares the screen with the download indicator. + (download_progress): If starting a download, unmap the search widget + and map the download progress indicator in its place. When downloading + is done, do the opposite. + (config_win): Bind the down and up arrow keys to directly scroll the + window. + (search): New method which searches for strings in the source window + and jumps to a particular line. + (set_state): Do not reset current_file to empty when an exe has been + downloaded. + (bp): Do not special case tracepoint debugging. + + * manage.tcl (manage_init): Add elements for function browser. + (manage_create): If GDBTK_TEST_RUNNING is set in the environment, + place all windows on the screen at +0+0. + + * prefs.tcl (pref_save): Add new preference category "search". + (pref_set_defaults): Add search preferences. + + * tracedlg.tcl (TraceDlg::destructor): Destroy the actions dialog is + it exists. + (add_action): Save the object returned from the window manager when + the actions dialog is opened so that we can later destroy it if + necessary. + (done): Clear ActionsDlg when the actions dialog is destroyed. + + * main.tcl (do_tstart): Do not disable the "Begin collection" menu + item when we issue a tstart. + + * console.tcl (paste): New method which handles all Paste events for + this window. + (Console): Bind the middle mouse button on unix to generate a paste + event. + Override default binding for button-2 motion to allow easier pasting + into the window. + Bind the paste event to the method paste. + +Wed Jun 17 13:50:48 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (reconfig): Recognize tab size changes. + + * src_pref.tcl (build_win): Add tab control. Remove extra frame. + Justify variable ballons text. Set activebackgrounds on + color buttons. + +Tue Jun 9 13:57:24 1998 Keith Seitz <keiths@cygnus.com> + + * helpViewer.tcl (HtmlViewer): Display appropriate help based on the + preference gdb/mode. + + * help/trace: Add help files for tracing. + + * main.tcl (gdbtk_tcl_preloop): Call gdbtk_update so that the + source window fills files into the combobox. + + * srcbar.tcl (_open_file): "cd" to directory, don't add it to the + search list. This never gets reset anywhere, so if multiple file + commands are added, we could get the wrong path. Call gdb_clear_file, + too. + + * interface.tcl (gdbtk_tcl_pre_add_symbol): Call the reset method + of the source window, too. + + * src.tcl (reset): New method used to clear the source window + whenever multiple file commands are used. + + * tdump.tcl (update): Erase the contents of the tdump window + when displaying a new dump. + + * stack.tcl (update): Errors from the backtrace can contain + backtrace info, too, so make sure we print as much of that as + possible. + + * register.tcl (build_win): Do not allow editing in tracing + mode. + (reg_select): Do not allow editing in tracing mode. + + * memory.tcl (update_address): Check that gdb's handling of chars and + char*s doesn't abort the update. + + * variables.tcl (build_win): Disable editing in tracing mode. + (build_menu_helper): Disable editing in tracing mode. + (getLocals): Use the builtin functions gdb_get_locals and + gdb_get_args to get all local variables. Concat lists together. + (Variable::value): Set a default value for "radix" in case + the regsub fails. + +Tue Jun 9 00:00:18 1998 Martin M. Hunt <hunt@cygnus.com> + + * interface.tcl (gdbtk_quit): No longer use quit_hook. + Just call "manage save". + * manage.tcl (manage): Remove manage quit. + (manage_quit): Deleted. + (manage_init): Remove quit_hook. + (manage_save): Use "Pref setd" instead of "pref set". + * prefs.tcl (pref_set_defaults): Remove quit_hook. + (pref_quit): Deleted. + +Mon Jun 8 16:15:33 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl (set_check_button): Check for existence of + button before trying to set its state. + +Mon Jun 8 13:31:08 1998 Martin M. Hunt <hunt@cygnus.com> + + * memory.tcl (build_win): Always Bind configure event to + newsize method. Change table widget to use incr_addr for + both incr and decr. Enable autorepeat. + (create_prefs): Set rheight (row height). + (newsize): Set rheight if necessary. Return if numbytes + is not zero. + (update_address): Move gdbtk_idle and gdbtk_busy calls to + update_addr. + (update_addr): Surround with gdbtk_idle and gdbtk_busy. + (incr_addr): Take an argument to indicate how much + to increment or decrement by. + (decr_addr): Deleted. + +Fri Jun 5 00:13:49 1998 Martin M. Hunt <hunt@cygnus.com> + + * Change all references to GDBTK_IDE to IDE_ENABLED. + +Thu Jun 4 18:34:11 1998 Martin M. Hunt <hunt@cygnus.com> + + * memory.tcl: Complete rewrite. Added many new features + and made it much faster. + + * mem_pref.tcl (build_win): Set listbox width. + + * images/check.gif: New image. Used in version of + memory window without a menubar. + +Thu Jun 4 10:53:33 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * tclIndex: regenerated. + + Merged (most recent first): + + - Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * tracedlg.tcl (ok): if the tracepoint does not exist (this can happen + if user is editing a tp and decides to remove it from tp window) + do not core dump, give an error message instead, and return. + + * bp.tcl (get_actions): invoke trace dialog from tracepoint window, + passing filename and line as arguments, rather than address. + + - Jeff Holcomb <jeffh@cygnus.com> + + * main.tcl (set_baud): Change gdb/load/$gdb_target_name/baud + to gdb/load/${gdb_target_name}-baud. + + - Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * tdump.tcl (update): call tdump only if the current trace frame + number is not -1. + + * interface.tcl (gdbtk_tcl_tstart): update menus entries only, do + not do actual command. + (gdbtk_tcl_tstopt): update menus entries only, do not do actual + command. + (gdbtk_tcl_warning): remove tdump warning message from list of not + displayed messages. + + * main.tcl (do_tstart): catch error output from tstart and display + error dialog. + (do_tstop): catch error output from tstop and display error dialog. + + * bp.tcl (bp_add): align properly the bpnum and passcount fields, + for the tracepoint window. + + * main.tcl (set_exe): set file_done (new global state variable) + depending whether new file was read in or not. + (set_target_name): return 0 if user chose cancel from target setting + window displayed by 'connect'. + (set_target): if no target_cmd is specified call set_target_name and + ask user for it. + (async_connect): handle possible outcomes of set_target command, + issue appropriate messages to user. + Initialize file_done to 0. + + * target.tcl (cancel): set gdb_target_name to CANCEL for use by + set_target_name. + Added public data 'exportcancel'. + + * toolbar.tcl (do_async_connect): change menu items state only + if connect was successful. + + * src.tcl (bp): modify condition for SOURCE case to display tp dot + after connecting to target. + + * actiondlg.tcl (constructor): make dialog non modal. + (destructor): release grab not any longer necessary. + (change): make lsearch use exact pattern matching for entries + added to the collect list using the 'other' field. The new syntax + allows array elements to be specified and this messes up the + default glob style pattern matching. + (change_other): reject memranges (obsolete). Delegate validation + of user input to the lower levels, in gdb. I.e. keep everything + until the whole tracepoint is installed. + + * tracedlg.tcl (gdb_add_tracepoint): call to gdb_actions is now + catching the errors (in case of incorrect syntax) and displaying + them to the user. + + * main.tcl (set_target): Changed text of error message to mention + the Target Settings dialog. + + * prefs.tcl: Set default preference for gdb/load/check to 0. + + * target.tcl (build_win): disable comparison with executable for + 'exec' targets. + (set_check_button): new method. Enable/disable the check button + for comparing executable. + (change_target): call set_chack_button when target changes. + Set default preference gdb/load/check to 0. + + * stack.tcl: set initial window width value to 40, so that window + looks better if opened before a stack exists. + + - David Taylor <taylor@texas.cygnus.com> + + * main.tcl (async_connect): remote-compare is now compare-sections. + + - Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * warning.tcl (constructor): call destructor if dialog doesn't + need to be displayed. + + * console.tcl (invoke): make function get input and return if in + readline state, independently from the value of Running. + + * src.tcl (set_state): set state of pop up menus only for synch + mode. + + * tdump.tcl (build_win): simplify the window, eliminating pane. + This fixes resize problems. + (update): add call to see to display last thing outputted to the + window. + + * tfind_args.tcl (do_it): call the tfind_cmd procedure. + + * toolbar.tcl (create_menu_items): changed calls to tstart and tstop + to use do_tstart and do_tstop. + + * srcbar.tcl (runstop): do not call _set_trace in asynch case, + just use _set_runstop always. + (_set_runstop): added handling for asynch mode cases. + (_set_trace): removed. + + * main.tcl (do_tstart): new procedure to execute tstart command + update tstart/tstop button, and menu entries accordingly. + (do_tstop): new procedure for tstop, as above. + (run_executable): calls do_tstart in the asynch case. + + * interface.tcl (gdbtk_tcl_tstart): new procedure to invoke + the tstart command + (gdbtk_tcl_tstop): new procedure to invoke the tstop command + + * interface.tcl: (gdbtk_tcl_warning) do not display warning + about no current trace frame upon opening of tdump window. + + * main.tcl: (run_executable) in asynch mode just call tstart, + connect is now done independently. + (async_connect) new procedure to connect and do comarison with + remote executable, in asynch mode. Sets up gui state globals. + (async_disconnect) new procedure to disconnect from target in + asynch mode. Sets up gui state globals. + + * prefs.tcl: added new preference gdb/load/check + + * srcbar.tcl: (create_buttons) tfind commands now use tfind_cmd + function + + * target.tcl: added new preference gdb/load/check to execute an + automatic remote-compare command on connection to target in asynch + mode + (set_saved) set saved value for new preference + (write saved) write saved value for new preference + (build_win) set state of 'run to main', 'break at exit', 'display + dowload' to disabled for asynch mode target dialog. + Added new checkbutton for automatic comparison of remote exec. + Saved_check: new protected member + + * tdump.tcl: (update) changed check for no frame, since 0 is legal + trace frame number. + + * toolbar.tcl: (create_menu_items): added menus items 'connect to + target' and 'disconnect', in async mode. Changed to call tfind_cmd + to execute tfind commands + (do_async_connect): new method to connect to target in async mode. + (do_asynch_disconnect): new method to disconnect from target in + async mode. + + * util.tcl: (tfind_cmd): new proc to execute a tfind command on + the target + +Thu May 28 12:49:29 1998 Keith Seitz <keiths@cygnus.com> + + * target.tcl: Add sparclite target. + (fill_targets): Add sparclite target. + + * main.tcl (set_target_name): Rearrange so that the default behavior + is to assume a remote-like target. + + * src.tcl (browse_to): Helper function for BpWin::goto_bp which causes + the source window to show the specified location. + + * bp.tcl (bp_add): Clean up repetitive code. + Add double-click binding which shows the breakpoint + in the source window. + (bp_select): Clean up repetitive code. + (goto_bp): New function. + +Sun May 24 14:05:27 1998 Keith Seitz <keiths@cygnus.com> + + * src.tcl (reconfig): Remove the variable balloon selection in the text + widget, too, when we are disabling varialbe balloons. + + * target.tcl: Add a "runlist" parameter to all gdb_target entries. This list + controls the default behavior of the run button. + (GdbLoadPref): Define the run preferences based on this target. + (build_win): Add a "more options" dropdown pane to allow users to modify the + behavior of the run button. + (set_saved): Add run button preferences. + (write_saved): Add run button preferences. + (fill_targets): Add the "pretty name" to the combo box, not gdb's internal + target name. + (change_target): Use get_target to translate the "pretty-name" to the + real target name. + (save): Write out saved values, too. + (get_target): New method to translate the "pretty-name" of a target into gdb's + internal name/ + (toggle_more_options): New method to handle mapping and unmapping of the + "more options" pane. + (set_run): New method. Moved from src_pref.tcl. + (valid_target): Moved here from main.tcl. + (native_debugging): Moved here from main.tcl. + (change_target): Don't write_saved here -- wait until dialog is closed. + + * src_pref.tcl (build_win): Use libgui's Labelledframe class instead of the + Tix labeled frame. + Remove the run button frame -- this has moved into the target selection dialog. + (set_run): Moved to targets.tcl. + + * prefs.tcl (pref_set_defaults): Change default preferences for the run + button to only do a run. Target selection will reset these as appropriate. + + * main.tcl (set_baud): Baud preferences are in TARGET-baud, not + TARGET/baud. + (run_executable): Remove special cases for exec targets. + (native_debugging,valid_target): Move to target.tcl. + + * images/more.gif, images/less.gif: New images for drop frames. + + * tclIndex: Regenerate. + +Wed May 20 13:43:00 1998 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_menu_items): Remove register prefs. + + * images/stop.gif: Set transparent bit. + +Tue May 19 12:34:11 1998 Keith Seitz <keiths@cygnus.com> + + * bp.tcl (bp_add): Use source window's colors. Use "file tail" not + "lindex [file split ] end". + (bp_modify): Use source window's colors. Use "file tail" not + "lindex [file split ] end". + (bp_remove): Call bp_select before we delete the breakpoint. + + * main.tcl (run_executable): Encapsulate all calls to debugger + based on new run preferences. + + * manage.tcl (manage_init): Change loadpref titles to "Target Selection" + + * pref.tcl (build_win): Disable Help button until it works. + + * prefs.tcl (pref_set_defaults): Define new run button preferences. + Lose stack and bp window color preferences -- use the source window + ones instead. Lose left_click, too. + + * src.tcl: Remove all references to _Source_Left_Click and replace with new + protected variable Tracing. Define new protected variable UseVariableBalloons + so that we don't follow the preferences blindly. Replace all preference calls + for these two globals. + (reconfig): Allow reconfiguration of variable balloons and popup menu colors. + (config_win): Add binding for File Menu->Open. + (do_key): Add open key. + + * src_pref.tcl (SrcPref): Save all newly added preferences. + (build_win): Add new preferences for mode, variable balloons, + lots of color choices. + (cancel): Reset all new preferences. + (pick): Allow passing of button in to make things a little easier. + (reconfig): Keep empty -- no need for this to reconfigure itself. + (set_run): New method to make sure someone does not try to run _and_ + continue a target with the run button. + + * stack.tcl (build_win): Use the source window's preferences to set colors. + + * target.tcl (build_win): Disable Help button until it works. + +Mon May 18 15:25:00 1998 Martin M. Hunt <hunt@cygnus.com> + + * html_library.tcl (HMstack): Remove stray 'g' that was + preventing autoloading. + +Mon May 18 13:17:30 1998 Keith Seitz <keiths@cygnus.com> + + * helpViewer.tcl (HtmlViewer): Initialize glossary. + (glossaryPost): Fill in skeleton supplied by jingham. + (glossaryUnpost): Ditto. + (lookup): New method to lookup glossary definitions. + (HMset_image): Add special image names. + +Fri May 15 00:30:06 1998 Martin M. Hunt <hunt@cygnus.com> + + * memory.tcl (update_address): Source window was never being + updated due to a faulty fencepost. I removed it. Was it + useful? + +Tue May 12 11:47:11 PDT 1998 James Ingham <jingham@leda.cygnus.com> + + * helpViewer.tcl: Made the fonts for the viewer track the global + font preferences + *html_library.tcl: Use Tcl Font objects for the fonts rather than + building up X Font Specs. + + +Thu May 7 16:03:32 1998 Keith Seitz <keiths@cygnus.com> + + * toolbar.tcl (create_menu_items): Remove automatic stepping. + (create_menu_items): "Cygnus on the Web..." should point to GNUPro page... + +Wed May 6 20:18:34 1998 Keith Seitz <keiths@cygnus.com> + + * main.tcl (set_target_name): Recognize d10v and m32r targets. + (valid_target): Change test to recognize all tcp targets. + + * target.tcl: Add m32r and d10v tcp targets. + +Wed May 6 12:52:12 1998 Keith Seitz <keiths@cygnus.com> + + * srcbar.tcl (create_menu_items): Install a page setup menu item for + non-ide debuggers. + + * src.tcl (print): Don't call idewindow_freeze and idewindow_thaw + the ide is not running + +Wed May 6 10:41:30 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * bp.tcl (get_actions): set bpnum to be the real tracepoint number, + not the selected row number. + +Tue May 5 04:07:12 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl: Add D10V and M32R target. + + * prefs.tcl (pref_set_defaults): Set debugging off + by default. + +Fri May 1 15:23:57 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * main.tcl (valid_target) make 'remotetcp' a valid + target. + +Fri May 1 11:50:40 1998 Jim Ingham <jingham@leda.cygnus.com> + + * helpViewer.tcl: Added the skeleton for the Glossary entries. + Fixed the zoom to top of page when rendering is complete nit. + Added a reconfig method to refresh the current page. + Compulsive reordering of methods. + +Thu Apr 30 00:04:52 1998 Martin M. Hunt <hunt@cygnus.com + + * global_pref.tcl (change_icons): Remove debug line. + + * toolbar.tcl: Change image names to end with _img + so they don't conflist with command names. + * srcbar.tcl: Same. + +Tue Apr 28 16:51:09 1998 Jim Ingham <jingham@leda.cygnus.com> + + * html_library.tcl: The redefinition of tkFocusOK in this file + can cause an infinite recursion loop in autoloading tkFocusOK. + Change proc -> ::proc to hide the definition from itcl_mkindex + * tclIndex: remade without the reference to tkFocusOK. + +Tue Apr 28 16:51:09 1998 Jim Ingham <jingham@leda.cygnus.com> + + * helpViewer.tcl: The index page now shows up properly in the + history list. Also added images for the fore, back and home + buttons, and removed the close button. + + * manage.tcl: Moved the wm withdraw of a new toplevel before the + constructor is run in manage_create. This avoids flashing. + + * main.tcl: Changed the tk application name of gdbtk from tk + to gdbtk. + +Mon Apr 27 14:18:01 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * helpViewer.tcl: (constructor) Change 'Foreward' to 'Forward' and + calls to 'foreward' method to calls to 'foreward' method. + (forward) changed method name from 'foreward'. + +Thu Apr 23 19:02:25 1998 Keith Seitz <keiths@onions.cygnus.com> + + * toolbar.tcl (create_menu_items): Use the new help viewer when not + using the IDE. + + * helpViewer.tcl (HtmlViewer::constructor): Set default values for + previously passed-in variables. + (HtmlViewer::destructor): Destroy the toplevel, too. + (HMset_image): prepend the dir name "images" to the image path. + +Thu Apr 23 13:31:07 1998 Jim Ingham <jingham@leda.cygnus.com> + + * html_library.tcl: First checkin + * helpViewer.tcl: First checkin + * manage.tcl (manage): Added the help veiwer to the windows + list. Aslo compulsively alphabetized the list... + * tclIndex Rebuilt for the new procs. + +Mon Apr 20 11:14:17 1998 Keith Seitz <keiths@onions.cygnus.com> + + * global_pref.tcl (build_win): Add font selector for the status font. + + * main.tcl (run_executable): Exec targets are always "loaded". + +Sat Apr 18 02:11:04 1998 Martin M. Hunt <hunt@cygnus.com> + + * prefs.tcl (pref_read): Remove debug line. + + * util.tcl (toggle_debug_mode): When enabling or + disabling debugging, also enable or disable error + reporting and stack traces. + +Sat Apr 18 01:13:03 1998 Martin M. Hunt <hunt@cygnus.com> + + * srcbar.tcl (_toggle_updates): Cleanup. + + * src.tcl (do_popup): Fix problems with selections. While + I'm messing with this code anyway, change how it works + so that the popup will contain the word that is under the cursor + if nothing is selected. + + * toolbar.tcl (create_buttons): Bind button 3 to create + new windows when possible. + + * stack.tcl (StackWin): Fix broken deiconify call. + + * images/[console.gif, reg.gif]: Update. + +Fri Apr 17 10:34:23 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (location): Don't look up the full pathname + of each file added to the combobox. + +Fri Apr 17 09:58:59 1998 Keith Seitz <keiths@onions.cygnus.com> + + * target.tcl (default_port): New proc. Returns a default port + based on host os. + (startup code): Use default port to determine the default port + to use for all hosts. + (build_win): Only set the target if it is valid. + For unix, use port names that correspond to the OS running. + Change gdb/load/$target-portnum to gdb/load/$target-port (typo?) + (get_target_list): Do not allow "exec" for cross debugging. + (save): Do not do dismiss dialog if the target is not valid. + (cancel): If exportcancel is set, set gdb_target_cmd to "CANCEL". This + will allow run_executable to cancel a run if the user cancels target + selection. + (exportcancel): New public data. + + * main.tcl (set_target_name): Return status to caller so that the user + can cancel a run request when the target selection dialog is opened. + Do not modify gdb_exe_changed -- it has already been set proprely. + (set_target): If gdb_target_cmd is empty, call set_target_name to + set it. + Allow all set_target_name commands to cancel target selection. + (run_executable): Allow all set_target_name commands to cancel + target selection. + Always clear bp's at main and exit, since this proc will set them + for all targets now. + Save the bp number for the breakpoint installed at main and exit so + that we can reliably delete them if the user cancels any subsequent + target selection. + Whenever the run is canceled, delete the breakpoints at main and exit. + Move setting of breakpoints at main and exit from download_it here. + (valid_target): New proc. Returns true if the given target is a valid, + runnable target. + (native_debugging): New proc. Returns true if this gdb is not a cross + gdb. + (startup code): Do not call set_target_name here -- let run_executable + do it. + + * interface.tcl (gdbtk_tcl_query): Update the display when this dialog + is dismissed. + (gdbtk_tcl_warning): Always show warnings in the debug window. + + * download.tcl (download_it): Move setting breaks at main,exit to + run_executable in main.tcl. + +Thu Apr 16 11:28:01 1998 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (set_target_name): Add "prompt" parameter + which allows this function to be called without it always + prompting for the target name. This allows it to quietly + initialize variables from preferences. + (set_target): Remove HACK_FIRST_HACK. + (run_executable): Check the result of [set_target]. + If it fails, prompt for a new target and repeat. + (startup code): Remove HACK_FIRST_HACK. + Call set_target_name to initialize gdb_target_cmd from + preferences. + + * toolbar.tcl (create_menu_items): Call set_target_name + for the target menu item. This will open the dialog and + then set the target command correctly. + + * target.tcl (save): Set default target preference. + +Wed Apr 15 11:29:47 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (reconfig): Tell toolbar to reconfig. + + * global_pref.tcl (build_win): Add support for changing + icons. Put fonts in a labelled frame. + (update_file): Removed. + (change_icons): Callback for icon combobox. + + * srcbar.tcl (_load_src_images): Remove old target and + load images. Add reconfig parameter which reloads images. + Use global gdb_ImageDir. + (reconfig): New method. + + * floatbar.tcl (create_buttons): Remove target image. + Use global gdb_ImageDir. + + * toolbar.tcl (_load_images): Use global gdb_ImageDir. + Add reconfig parameter which reloads images. + (reconfig): Don't rebuild everything, just reload images. + (create_menu_items): Change "Fonts" preferences menu + item to "Global". + + * prefs.tcl (pref_set_defaults): Save only basename in + gdb/ImageDir preference. Initialize global gdb_ImageDir. + (pref_read): Set gdb_ImageDir. + + * memory.tcl (build_win): Use global gdb_ImageDir. + + * manage.tcl (make_icon_window): Use global gdb_ImageDir. + + * about.tcl (build_win): Use global gdb_ImageDir. + + * images/icons.txt: New file; icon descriptions. + * images/vmake.gif: New file. + * images/vars.gif: New file. + * images/watch.gif: New file. + * images/bp.gif: New file. + * images/memory.gif: New file. + + * images2/icons.txt: New file; icon descriptions. + + * toolbar_pref.tcl: Removed. + + * main.tcl (run_executable): If target is "exec" don't + show target dialog unless the run command fails. + +Wed Apr 15 13:15:22 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * interface.tcl: (gdbtk_tcl_warning) changed to selectively + display warnings in the GUI. + (show_warning) new procedure. Displays warning dialogs. + +Wed Apr 15 07:13:04 1998 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (do_popup): Fix merge casualty -- revert to pre-3/22 version. + Don't allow tracepoint ranges to be set unless in asynch mode. + +Mon Apr 13 16:00:06 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * warning.tcl: new file. Implements WarningDlg class, for warning + dialogs. + + * tclIndex: regenerated + + * Makefile: added new file warning.tcl + + * manage.tcl: added new window warningdlg, for ignorable warnings. + + * interface.tcl: (gdbtk_tcl_warning) new procedure. Creates a warning + dialog. + (gdbtk_tcl_ignorable_warning) new procedure. Creates a warning dialog. + The user can choose to not have this dialog pop up again during the + same debugging session. + +Mon Apr 13 13:04:20 1998 Keith Seitz <keiths@onions.cygnus.com> + + * stack.tcl (StackWin::constructor): Withdraw toplevel before calling + all busy hooks; then build the window, go idle and pop the window onto + the screen. + + * main.tcl (set_target_name): Use a regexp to match target names. + Add "sds" as a target. + (run_executable): Use gdb_immediate to run executable. + +Fri Apr 10 10:27:42 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * bp.tcl: changed default value of public var tracepoints to be 0. + +Thu Apr 9 15:21:49 1998 Martin M. Hunt <hunt@cygnus.com> + + * global_pref.tcl (destructor): Delete test fonts here instead of + in ok and cancel. This fixes bug when dialog was closed by + clicking on close gadget. + + * src_pref.tcl (pick): When colors are changed, immediately + update the dialog. + +Thu Apr 9 04:03:27 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl (build_win): Bind <Return> for cancel and help buttons. + +Wed Apr 8 10:57:14 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * tdump.tcl: (update): show stuff on window only if current + trace frame is not null. + + * variables.tcl: (build_win): get the current output-radix + (getVariables): decide the format to display a var based on Radix + VariableWin class: added protected member Radix + (value): decide display based on output-radix + +Wed Apr 8 06:17:42 1998 Keith Seitz <keiths@onions.cygnus.com> + + * bp.tcl (get_actions): Open the trace dialog based on a tracepoint's + number. + + * tracedlg.tcl (title): New method to title window based on mode. + (TraceDlg::constructor): After the interp is idle, title this window. + (build_win): Add support to simply pass a tracepoint number for editing. + +Tue Apr 7 12:49:45 1998 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl (VariableWin): We should deiconify after withdrawing... + + * tracedlg.tcl (gdb_edit_tracepoint): Make necessary gdb_cmd changes + to support new API. + (gdb_add_tracepoint): Make necessary gdb_cmd changes to support new + API. + + * tdump.tcl (update): Make necessary gdb_cmd changes to support new + API. + (TdumpWin::constructor): We should deiconify after we withdraw... + Change idle callback to an update callback. + (TdumpWin::destructor): Change idle callback to update callback. + + * srcbar.tcl (_open_file): Make necessary gdb_cmd changes to support new + API. + (create_buttons): Change all tracing commands to use gdb_immediate. + + * main.tcl (set_target_name): Add simulator target. + + * src.tcl (mode): When changing modes, clear the line to pc mappings. + (location): Do not set current_addr if we are not running and gdb_loc + thinks we're at 0x0. + Clear the text-window-line to pc mapping when appropriate. + Revert display_breaks change for SRC+ASM mode. + (bp): Make sure mapping of PC to src window line exists before + attempting to set breakpoints/tracepoints. + +Fri Apr 3 13:57:42 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * src.tcl: (do_key): added actions for key bindings in trace mode. + (config_win): added key bindings for trace mode. + + * srcbar.tcl: (_set_trace) changed balloon contents for tstart/ + tstop button. + + * toolbar.tcl: (create_menu_items): changed names of menu items + tstart and tstop to 'Begin Collection' and 'End Collection'. + Changed name of Preference menu item from 'GDB' to 'Fonts'. + Changed name of File menu item from 'Debugger Preferences' to + 'Target Settings'. + Commented out Preference menu item 'Download'. + (create_buttons): tdump button, inserted text 'Td' in place of missing + icon. + + +Tue Mar 31 17:20:59 1998 Ian Lance Taylor <ian@cygnus.com> + + * Makefile (TCL): Add ide.tcl. + * tclIndex: Rebuild. + +Sun Mar 29 18:50:46 1998 Keith Seitz <keiths@onions.cygnus.com> + + * tracedlg.tcl (build_win): Enable tracepoints at assembly addresses. + (add_action): Enable tracepoints at assembly addresses. + (ok): Enable tracepoints at assembly addresses. + (edit): Enable tracepoints at assembly addresses. + (gdb_add_tracepoint): Enable tracepoints at assembly addresses. + + * srcbar.tcl (_open_file): If main () exists, show it. + + * src.tcl (display_breaks): If we are displaying breaks in assembly, + clear the line and file specs. + (location): Use display_breaks to insert breaks and traces. + (bp): Rewrite. Actions are based on mode of the source window. + (bp_line): When setting a tracepoint in assembly, pass address + to set_tracepoint. + (set_tracepoint): Open trace dialog specifying either line or + address at which to set trace. + (tracepoint_range): Rewrite. Actions are based on the mode of the + source window. Now able to insert ranges of traces in any mode. + + * actiondlg.tcl (ActionDlg::constructor): Enable widget via address + specification. + (ActionDlg::Line): Default to empty list. + (ActionDlg::Address): Add new memeber to enable assembly operation. + +Sun Mar 29 21:21:37 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * bp.tcl: add tracepoint number to tracepoint window. + (build_win)(bp_add)(bp_select)(bp_modify)(bp_delete) + + * manage.tcl: (manage_init) do not open windows not related to + current mode + + * tdump.tcl: (reconfig) remove it + (config) add toplevel window, show window after it has been built. + (update) add calls to busy and idle hooks, add third argument to + gdb_cmd call + +Sun Mar 29 15:01:03 1998 Keith Seitz <keiths@onions.cygnus.com> + + * srcbar.tcl (_set_trace): Use gdb_immediate to execute the "tstop". + Call run_executable when requesting a tstart. + (_open_file): Convert all paths under cygwin32 to a posix-compliant + pathname. Add this path to the source search list. + + * src.tcl (set_execution_status): Change stop messages to support + tracing. + (tracepoint_range): Clear the selection when we set a range of + tracepoints. + + * main.tcl (set_target): Use gdb_immediate so that the console gets + output of target command. + (run_executable): Use gdb_immediate for run command. + Include trace support. + +Sat Mar 28 15:50:01 1998 Keith Seitz <keiths@onions.cygnus.com> + + * srcbar.tcl (create_menu_items): Put menu items in proper order. + (_open_file): Add exe file's directory to the default source + search path. + +Sat Mar 28 14:29:08 1998 Keith Seitz <keiths@onions.cygnus.com> + + * srcbar.tcl (GDBSrcBar: runstop trace): If running async'ly, set + the run/stop button by calling _set_trace. Otherwise use _set_runstop. + (create_menu_items): Add file command to open a new exe. + (_open_file): New method to handle requests to open a new exe. + + * main.tcl (set_target): If this is the first time running, + then show the download prefs dialog. + +Sat Mar 28 16:30:55 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * tracedlg.tcl: (build_win) reinserted 'update idletasks' to + display Actions frame properly. + + * actiondlg.tcl: (sort) moved "All Registers", "All Locals", + "All Arguments" to beginning of list. + + * src.tcl: (line_is_executable) new method. Used in + tracepoint_range. + +Sat Mar 28 10:58:04 1998 Keith Seitz <keiths@onions.cygnus.com> + + * tracedlg.tcl (gdb_edit_tracepoint): Don't let gdb_cmd call busy and + idle hooks. + (gdb_add_tracepoint): Ditto. + + * src.tcl (config_win): Change exit key binding from 'q' to 'x.' + (goto_func): That's "file tail", not "file split." + + * srcbar.tcl (_set_stepi): Don't do anything if we're debugging + asynchronously. + +Sat Mar 28 10:09:21 1998 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_menu_items): Change "Close Debugger" + menu item to "Exit". + +Sat Mar 28 02:38:51 1998 Martin M. Hunt <hunt@cygnus.com> + + * src_pref.tcl (build_win): Fix Save and Apply buttons. + Change "Save" to "OK". Use standard_button_box. + (save): New method, save and exit. + (apply): New method; save and don't exit. + (cancel): New method; cancel all changes. + + * src.tcl (reconfig): Reconfigure colors, too. + + * global_pref.tcl (Globalpref): Fix deiconify call. + (build_win): Use standard_button_box. Set default to OK. + Remove unused stuff. Cleanup display. + + * Makefile: Removed toolbar_pref.tcl. + + * tclIndex: Rebuilt. + + * srcbar.tcl (create_buttons): Make toolbar always attached + to source window. + + * toolbar.tcl (build_win): Always display toolbar and + menubar attached to source window. + + * prefs.tcl (pref_set_defaults): Removed toolbar prefs. + + * manage.tcl (manage_init): Remove hack to change preferences + names. + (manage_init): Remove toolbar and toolbar prefs code. + (manage_create): Remove toolbar code. + (manage_open): Remove toolbar code. + (manage_find): Remove toolbar code. + (manage_delete): Remove toolbar code. + (manage_restart): Remove toolbar code. + +Fri Mar 27 19:52:53 1998 Keith Seitz <keiths@onions.cygnus.com> + + * toolbar.tcl (create_menu_items): Do not disable preferences. + + * src.tcl (reconfig): Rewrite to not destroy window. + Symbolic fonts are a blessing! + Pass the image handles for our breakdots to makeBreakDots. + (file): Move breakpoint/tracepoint insertion to a separate function... + (display_breaks): .... this one. + (location): Move the block which fills combo boxes to top in + case an error causes us to exit early. + (makeBreakDot): Accept an optional image handler so that it can be + configured instead of created. + + * global_pref.tcl (build_win): Carry around a list of all changable + fonts in case more granularity is needed. (Windows cannot change + menu font...) Disable menu font for windows. + (ok): Check the list of changable fonts. + (cancel): Check the list of changable fonts. + (apply): Check the list of changable fonts. + + * console.tcl (reconfig): New (empty) method to handle preference + changes. + +Fri Mar 27 16:08:57 1998 Keith Seitz <keiths@onions.cygnus.com> + + * global_pref.tcl (ok): Must use preferences for comparison. Don't + "manage restart" unless needed. + (cancel): Don't configure the font -- changing the preference will do + it automagically. + +Fri Mar 27 14:21:02 1998 Keith Seitz <keiths@onions.cygnus.com> + + * toolbar.tcl (create_menu_items): Use gdbtk_quit to initiate a quit. + + * src.tcl (do_key): Use gdbtk_quit to initiate a quit. + + * prefs.tcl (pref_save): Set a default value for WIN. + Don't "manage restart". + (pref_set_defaults): Register a quit hook to save preferences. + (pref_quit): Call pref_save to save all preferences when we quit. + + * manage.tcl (manage): Add "quit". + (manage_init): Register a gdb_quit_hook. + (manage_delete): Instead of guessing when and what to ask to confirm + a quit, call gdbtk_quit. + (manage_quit): New procedure. This is called from the gdb_quit_hook to save + window active'ness and geometries by calling manage_save. + + * interface.tcl: Define "gdb_quit_hook". + (gdbtk_quit): New procedure to call whenever a quit is requested. + + * global_pref.tcl (ok): Do not save preferences here. + +Fri Mar 27 12:21:07 1998 Keith Seitz <keiths@onions.cygnus.com> + + * tracedlg.tcl (TraceDlg): Wait until idle to deiconify ourselves. + + * global_pref.tcl (Globalpref): Withdraw window before creating and + deiconify it when idle. + (cancel): Let the window manager destroy us. + (ok): Let the window manager destroy us. + + * target.tcl (GdbLoadPref::constructor): Withdraw window before creating + and deiconfiy it when idle. + + * memory.tcl (MemWin::constructor): Withdraw window before going + busy. + + * register.tcl (RegWin::constructor): Withdraw window before going + busy. + + * src.tcl (SrcWin::constructor): Withdraw window before creating and + deiconify it when idle. + +Fri Mar 27 10:52:30 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl: Fix entry for temotetcp. + + * main.tcl (set_target_name): Build correct gdb_target_cmd. + +Fri Mar 27 11:23:18 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * target.tcl: (build_win) added call to change_target to + get the correct entry widgets when the dialog is opened. + +Fri Mar 27 01:43:41 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl: Add simulator and remotetcp targets to + target database. Change all the gdb/load/$target/foo + preferences to gdb/load/$target-foo because the prefs + code expects gdb/section/varname. The extra slash confuses + it. + (set_saved): Add saved_portname and saved_hostname for TCP. + (write_saved): Add saved_portname and saved_hostname for TCP. + (fill_rates): change states of hostname and portnum entry widgets. + (fill_targets): Add fake remotetcp entry in target list. + (change_baud): When switching between tcp and serial targets + pack or forget the appropriate widgets. + (build_win): Create hostname and port number entry widgets. + (change_target): Update hostname and portnum widgets. + + * prefs.tcl (pref_save): Add 'load' as a section to be saved. + Set gdb/load/target to 'exec'. + + * manage.tcl (_manage_null_handler): Deleted. + + * download.tcl (download_it): Don't call IDE functions + unless GDTK_IDE is set. + + * main.tcl (gdbtk_tcl_preloop): Get name of executable + if one was supplied on command line. + (set_target_name): Save target name as preference. + (run_executable): Call set_target. + +Fri Mar 27 00:23:46 1998 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (location): Catch error of getting location of main. + + * prefs.tcl (pref_set_defaults): Add gdb/toolbar/active. + Add trace for global/fixed font to update src-font. + (pref_read): Add code to deal with global preferences. + (pref_save): Add code to deal with global preferences. + (pref_src-font_trace): Trace function which set src-font to global/fixed. + + * global_pref.tcl (build_win): Relayout font selectors and add a selections + for menu and default fonts. + Rename Save to OK and Quit to Cancel, renaming methods, too. + (font_changed): Add arguments to facilitate multiple fonts. + (reconfig): Define as empty. + (ok): Rewrite to facilitate multiple fonts. + (cancel): Rewrite to facilitate multiple fonts. + (apply): Rewrite to facilitate multiple fonts. + + * manage.tcl (manage_restart): Call gdbtk_idle to reset the toolbar after + it is recreated. + +Thu Mar 26 23:49:26 1998 Martin M. Hunt <hunt@cygnus.com> + + * tdump.tcl, tfind_args.tcl: New files. + +Thu Mar 26 22:29:28 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * tracedlg.tcl: (config) commented out grab. Made window non-modal. + (destructor) do not release grab. + (done) do not reinstall grab. + + * toolbar.tcl: (create_buttons) changed buttons for the tracepoint + case to open tdump window, and tracepoint window. + (create_menu_items) change Run menu to do tstart, tstop for tracepoint + case. Changed View menu to show tracepoint window for tracepoint case. + Changed 'Control' menu to 'Trace' menu for tracepoint case, with + tfind commands. + + * srcbar.tcl: (create_buttons) changed the buttons for the + tracepoint case to do tfind commands. + (_set_trace) new method. Toggles tstart/tstop button. + + * src.tcl: (config) decide defatul action for left click on + source based on 'mode' preference. + (bp_line) ditto. + (config_win) modify pop upmenu on source window to display only + 'set tracepoint'. + + * prefs.tcl: (pref_set_defaults) added preference gdb/mode for + tracepoints or breakpoint display. + + * manage.tcl: (manage_init) added tracepoint window, args windows + for tfind, tdump window. + (manage_open) use eval in call to manage_create. + + * bp.tcl: (build_win) added PassCount to the display and modified + the menus for the tracepoint case to display actions. + (bp_add) display pass_count too in the tracepoint list. + (bp_select) changed indexes of menu entries to be entries names. + added field passcount to selection for tracepoints. + (bp_modify) added passcount for tracepoints. + (bp_delete) added passcount for tracepoints. + (get_actions) new method + Added new public member "tracepoints" to decide which kind of window + needs to be displayed. + + * Makefile: added new files tfind_args.tcl and tdump.tcl. + + * tclIndex: regenerated + +Thu Mar 26 14:23:00 1998 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (set_target_name): Make target dialog always + on top. + + * target.tcl (build_win): Bind Return to save. + (GdbLoadPref): Denter dialog on screen. + +Thu Mar 26 14:16:36 1998 Keith Seitz <keiths@onions.cygnus.com> + + * memory.tcl (update_address): Catch errors to update_addr so that + we do not error and leave the GUI busy. + +Thu Mar 26 13:51:58 1998 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_menu_items): Remove "Cygnus + Foundry Tour" and "Submit a PR" from the menu. + + * src.tcl (file): Set title to GDB. + + * manage.tcl (manage_init): Set About name. + + * main.tcl (set_target): Set title to GDB. + + * interface.tcl (gdbtk_tcl_query): Set title correctly. + + * Makefile: Remove download_pref.tcl. + +Thu Mar 26 11:33:02 1998 Keith Seitz <keiths@onions.cygnus.com> + + * Makefile: Add target.tcl to list of sources. + + * tclIndex: Rebuilt. + + * target.tcl (GdbLoadPref): Trace changes to gdb_loaded. + (target_trace): New procedure. This is invoked by a write trace + to gdb_loaded. + + * interface.tcl (gdbtk_busy): New procedure to run all busy hooks + (gdbtk_update): New procedure to run all update hooks + (gdbtk_idle): New procedure to run all idle hooks. Also runs the + no inferior hooks if no inferior has been created. + Rename old gdb_idle_hook to gdb_update_hook for clarity. + Change all references of run_hooks to use gdbtk_busy, gdbtk_idle, and + gdtk_update. + + * download.tcl: Make busy/update/idle hook changes. + + * main.tcl: Make busy/update/idle hook changes. + (set_exe): Clear gdb_loaded whenever a new exec file is selected. + + * manage.tcl: Make busy/update/idle hook changes. + + * mem_pref.tcl: Make busy/update/idle hook changes. + + * memory.tcl: Make busy/update/idle hook changes. + + * register.tcl: Make busy/update/idle hook changes. + + * src.tcl: Make busy/update/idle hook changes. + + * stack.tcl: Make busy/update/idle hook changes. + + * variables.tcl: Make busy/update/idle hook changes. + + Merged with Foundry 1.0: + Wed Mar 25 14:22:28 1998 Keith Seitz <keiths@onions.cygnus.com> + + * register.tcl (reconfig): Call busy and idle hooks. + + * memory.tcl (update_address): Call busy and idle hooks. + + Wed Mar 25 11:38:49 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (location): Fix typo. + + Tue Mar 24 21:03:01 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (location): If gdb_listfuncs returns an error, display + an error message that says the file was either not found or contained + no debugging information. + (location): When disassembling, put busy and idle calls before + and after. Set "NoRun" to indicate the busy hook should not + display the stop sign because the target isn't running, GDB may + just take a few seconds to do the disassembly. + (busy): Hack to support NoRun mode. + + * srcbar.tcl (_set_runstop): Add another case to disable the + Run icon instead of changing it to a stop sign. + + * main.tcl (set_exe): If the file has no debugging information, + display an error message and exit. This should only happen with + intentionally stripped files. + + Tue Mar 24 17:04:36 1998 Keith Seitz <keiths@onions.cygnus.com> + + * mem_pref.tcl (build_win): Keep track of all widgets that should be + disabled when busy. + (busy): New method which disables anything that could cause trouble. + (idle): New method which re-enables anything that "busy" disables. + (apply): Call busy and the busy hooks before doing update of memory + window. Then call idle and the idle callbacks when we are done. + + Tue Mar 24 12:07:52 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (location): Filter out .s and .S files because + Foundry does not yet support assembly source debugging. + + Tue Mar 24 08:50:46 1998 Keith Seitz <keiths@onions.cygnus.com> + + * register.tcl (but3): Don't pop up the right-click menu if we are + running. + + * download.tcl (download_it): Force an update so that all windows + are created and get their busy hooks called. + + * console.tcl (invoke): Make sure we are not running. + (busy): New method. + (idle): New method. + + Mon Mar 23 15:00:57 1998 Drew Moseley <dmoseley@cygnus.com> + + * src.tcl: (location): Assume we are locating main() if the target is + not running and we can't figure out which function we are in. + + * main.tcl (run_executable): Change to assembly mode when we try to + load a blank file. This usually means that source level debugging + was not enabled when this file was compiled. + + Reverse the parameters to src method::location() method invocation so + they are in the correct order + + Mon Mar 23 12:04:23 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (update): Comment out debug lines. + + * main.tcl (set_target_name): If the target name changes, + force a new "file" command to be issued by setting + gdb_exe_changed. + + Sat Mar 21 00:09:37 1998 Martin M. Hunt <hunt@cygnus.com> + + * download.tcl (download_it): Remove call to run_idle_hooks. + + * src.tcl (no_inferior): Call set_execution_status. + + * bp.tcl (bp_modify, bp_delete): Change to take an entry + number. + (update): Sometimes "create" calls are for existing + breakpoints and should be "modified" calls. Detect this + and pass the entry number to bp_delete or bp_modify. + + Fri Mar 20 22:50:55 1998 Tom Tromey <tromey@cygnus.com> + + * console.tcl (insert): Remove all \r characters from string to be + inserted. + + Fri Mar 20 01:55:14 1998 Keith Seitz <keiths@cygnus.com> + + * watch.tcl (validateEntry): Fencepost for running. + + * variables.tcl (VariableWin): Use "add_hook_before". + (idle_done): New gdb_idle_done_hook for this object. + (update): Don't call enable_ui here. + (enable_ui): Change cursor for this object. + (disable_ui): Ditto. + (no_inferior): Ditto. + + * toolbar.tcl (GDBToolBar): Use "add_hook_before". + + * stack.tcl (StackWin): Use "add_hook_before". + (StackWin): Encapsulate creation of this object with + busy and idle hooks so that the user gets some feedback and to + prevent other widgets from attempting to update. + (update): Add some sanity checking so that we do not update with + garbage in the window. + (idle_done): New gdb_idle_done_hook for this object. + (change_frame): Fencepost for running. + (busy): New gdb_busy_hook for this object. + (no_inferior): New gdb_no_inferior_hook for this object. + (cursor): New helper method to set the cursor of all subwindows. + + * src.tcl (SrcWin): Use "add_hook_before". + (toggle_updates): Use "add_hook_before". + (stack): Encapsulate creation of the stack object with + busy and idle hooks so that the user gets some feedback and to + prevent other widgets from attempting to update. + (idle_done): New gdb_idle_done_hook for this object. + (set_execution_status): When Program is Terminated..., reset + gdb_running. + (config_win): Pull mouse pointer cursor assignments in text widget + out into a separate function. + (bind_src_tags): New method to set the cursor for the window's text + widget tags. + (disable_ui): Call bind_src_tags to change cursor to "watch". + (enable_ui): Ditto. + (no_inferior): Ditto. + (cursor): New helper method to set the cursor of all subwindows. + + * register.tcl (RegWin): Encapsulate creation of this object with + busy and idle hooks so that the user gets some feedback and to + prevent other widgets from attempting to update. + Use "add_hook_before". + (reg_select_up): Fencepost for running. + (reg_select_down): Fencepost for running. + (reg_select_right): Fencepost for running. + (reg_select_left): Fencepost for running. + (reg_select): Fencepost for running. + (edit): Fencepost for running. + (idle_done): New gdb_idle_done_hook for this object. + (busy): New gdb_busy_hook for this object. + + * memory.tcl (MemWin): Encapsulate creation of this object with + busy and idle hooks so that the user gets some feedback and to + prevent other widgets from attempting to update. + Use "add_hook_before". + (create_prefs): Fencepost for running. + (idle_done): New gdb_idle_done_hook for this object. + (edit): Fencepost for running. + (newsize): Fencepost for running. + (busy): New method to block UI while running inferior. + (do_popup): Fencepost for running. + (cursor): New method to change the cursor definition for this + object. + + * manage.tcl (manage_init): Use "add_hook_before". + + * main.tcl (run_executable): Use "run_idle_hooks". + + * ide.tcl (gdbtk_ide_init): Don't create the source window here. + + * interface.tcl: Define new hook "gdb_idle_done_hook" -- to be called + when the debugger does completely idle to allow input to objects + again. + (run_idle_hooks): New procedure to wrap the idle hooks. + (gdbtk_tcl_idle): Split the idle callbacks into two parts: one that + only updates widgets and one that tells widgets to accept input + again. + + * download.tcl (Download): Use add_hook_before instead of add_hook. + (download_it): Use run_idle_hooks instead running the idle hooks + directly. + + * bp.tcl (BpWin): Use add_hook_before instead of add_hook. + + Wed Mar 18 18:59:00 1998 Sean Mahan <smahan@cygnus.com> + + * download.tcl (download_hash): Added an 'update' so the + status bar would work on an MBX board. + + Wed Mar 18 01:50:19 1998 Martin M. Hunt <hunt@cygnus.com> + + * prefs.tcl (pref_set_defaults): Define gdb/src/tab_size + to default to a tab size of 4. + + * src.tcl (setTabs): Set up tabs correctly. + + * download.tcl (download_it): Set correct state after + user cancels download. + + Tue Mar 17 12:30:23 1998 Tom Tromey <tromey@cygnus.com> + + * console.tcl (throttle): New public variable. + (insert): Delete initial text when past the throttle limit. + + Tue Mar 17 13:31:38 1998 Keith Seitz <keiths@onions.cygnus.com> + + * ide.tcl (gdb_exit_check): Do not let gdb confirm the quit if we + are downloading. + + Tue Mar 17 13:25:22 1998 Keith Seitz <keiths@onions.cygnus.com> + + * console.tcl (insert): Force update of screen. + + Mon Mar 16 10:22:00 1998 Sean Mahan <smahan@cygnus.com> + + * toolbar.tcl (create_menu_items): Added 'Submit PR' to the + help menu. For PR15334 + + Sun Mar 15 15:01:27 1998 Tom Tromey <tromey@cygnus.com> + + * interface.tcl (gdbtk_tcl_fputs): Don't call update. + + * src.tcl (build_win): Changed capitalization on balloon help. + + Fri Mar 13 10:01:48 1998 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (mode): Add a horizontal scrollbar to the assembly pane + of SRC+ASM mode when necessary. + + Fri Mar 13 00:47:59 1998 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (run_executable): Don't force downloads for sim. + + * download.tcl (download_it): Don't bother calling calling set_baud + for sim. + + * manage.tcl (manage_delete): Deregister the window before deleting + it to prevent those annoying bgerror messages. + + Thu Mar 12 15:28:22 1998 Keith Seitz <keiths@onions.cygnus.com> + + * download.tcl (Download): Define a list of all sections. + (update_download): Loop through the list of sections, updating the + current section's progress and marking any previously loaded sections + as done, if needed. + (do_download_hooks): New procedure. + (download_hash): Use a timer to force update of GUI at regular + intervals -- GUI should not update 10,000 times a second. + + Tue Mar 10 06:32:24 1998 Keith Seitz <keiths@onions.cygnus.com> + + * interface.tcl (gdbtk_tcl_query): Allow caller to specify the default + button. If none is specified, it is set to 'yes'. + + * manage.tcl (manage_delete): While inferior is running, gdb_cmd returns + immediately, so we need to manually ask the user if he wants to quit. + + Tue Mar 10 10:52:09 1998 Martin M. Hunt <hunt@cygnus.com> + + * download.tcl (download_it): Change where old breakpoints + are cleared. + (done): Set focus on "OK" or delete. + + Tue Mar 10 05:23:42 1998 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (do_key): New method to wrap all keypresses. + (mode): Use do_key method. + (config_win): Use do_key method. + + Mon Mar 9 23:06:21 1998 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (download_progress): Add an optional message + parameter to the function for use with error messages. + Don't set_status twice on cancel. Call update if + load fails. + + * download.tcl (done): If 'msg' is set, it should be + displayed and download has failed. Update all source + windows. + (cancel): Don't delete window here. Let it get deleted + after call to method 'done'. + (download_it): If download failed, call done method + with error message. Force reissue of target command. + Handle set_target failures. + + * main.tcl (set_target): Check result of target command + to see if the user cancelled the command. + (run_executable): Use gdb_program_has_run instead of + gdb_app_running, which was removed everywhere. Force + download when gdb_program_has_run. If user cancels download + before the download starts, preserve previous state. + + Mon Mar 9 15:06:21 1998 Martin M. Hunt <hunt@cygnus.com> + + * console.tcl (invoke): After gdb_immediate() finishes + check to see if the window is still there. + + * main.tcl: Initialize gdbtk_state(console). + + * interface.tcl: Remove some unused globals. Replace gdb_console + with gdbtk_state(console). + (gdbtk_tcl_readline_*): Don't set gdbtk_state(console) every + time. Let manage.tcl do it. + + * manage.tcl (manage_create): Replace gdb_console with + gdbtk_state(console). Check for windows that were deleted, + but not actually gone yet. + (manage_delete): Replace gdb_console with gdbtk_state(console). + + Mon Mar 9 09:08:11 1998 Keith Seitz <keiths@onions.cygnus.com> + + * watch.tcl (build_win): Tweak layout of the entry and button, + switching to grid geometry manager. + +Thu Mar 26 01:22:23 1998 Martin M. Hunt <hunt@cygnus.com> + + * target.tcl: New file. Implements target dialog. + + * srcbar.tcl (_set_run): Remove because it was no longer used. + + * util.tcl (freeze): Only call idewindow_freeze when + using the IDE. + + * prefs.tcl (pref_set_defaults): Set default tab size to 4. + + * src.tcl (location): If gdb_listfuncs cannot find + functions, display error message. + (setTabs): Set real tabs according to gdb/src/tab_size. + + * main.tcl (set_exe): Check to see if file was stripped. + Cannot debug without some symbols. + (set_target_name): If target changes, set gdb_exe_changed + so new "file" command will be sent. When not using IDE, + display target requester. + + * manage.tcl: Set loadpref to GdbLoadPref. + +Wed Mar 25 14:13:52 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * manage.tcl (manage_init) added tracedlg and actiondlg windows. + +Wed Mar 25 14:08:51 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * interface.tcl (gdbtk_tcl_pre_add_symbol): New procedure. + (gdbtk_tcl_post_add_symbol): New procedure. + + * src.tcl (set_execution_status): Use "set_status" to write to the + status bar, not "set Status". + +Mon Mar 23 13:41:39 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * memory.tcl: Changes to support new faster gdb_get_mem(). + (do_popup): Add "Go To" and Open New Window" to the popup + menu. + +Sat Mar 21 21:18:06 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + Merged changes from Foundry (list follows in reverse chronological + order) + + Sean Mahan <smahan@cygnus.com> + * download_pref.tcl (help): Added method to display context + sensitive help. + + Keith Seitz <keiths@onions.cygnus.com> + * src.tcl (bp_line): Don't insert breakpoints if we're running. + (disable_ui): Disable selections. Workaround for TkTextDisplay bug. + (enable_ui): Enable selections. + (no_inferior): Enable selections. + + Tom Tromey <tromey@cygnus.com> + * toolbar.tcl (create_menu_items): Use gdb_immediate, not gdb_cmd, + so that output appears in console window. + * src.tcl (bp_line): Use gdb_immediate when running "continue". + (mode): Use gdb_immediate, not gdb_cmd, so that output appears in + console window. + (config_win): Likewise. + * srcbar.tcl (create_buttons): Use gdb_immediate, not gdb_cmd, so + that output appears in console window. + * console.tcl (lvarpush): Removed. + (_insertion): New method. + (_saved_insertion): New private variable. + (constructor): Don't let user use mouse to put cursor outside + command line. + * src.tcl (build_win): Use global/status font on status bar. + * interface.tcl (gdbtk_tcl_query): Moved vwait out of `if' + statement -- must vwait in all cases, not just in case when + question is actually asked. + + Keith Seitz <keiths@onions.cygnus.com> + * variables.tcl (deleteTree): Reset Locals and ChangeList, too. + + Martin M. Hunt <hunt@cygnus.com> + * toolbar.tcl (enable_ui): Don't always set stepi and nexti + buttons on. + + Keith Seitz <keiths@onions.cygnus.com> + * toolbar.tcl (no_inferior): Instead of enabling/disabling the + individual menus on Windows, disable each menu's entries. + (disable_ui): Ditto. + (enable_ui): Ditto. + + Keith Seitz <keiths@onions.cygnus.com> + * manage.tcl (manage_delete): Catch destruction of the src window when + downloading and ask user if this is what he intends. + (manage_init): Don't install idle, busy, and no_inferior hooks. Allow gdb + to exit whenever the user wants to. + * srcbar.tcl (cancel_download): download_cancel_ok is a global. + + Martin M. Hunt <hunt@cygnus.com> + * ide.tcl (receive_file_changed): Minor fix when a new + executable is built when GDB is running. + + Martin M. Hunt <hunt@cygnus.com> + * bp.tcl (bp_delete): If a selected breakpoint is deleted, + set "selected" to 0. + + Keith Seitz <keiths@onions.cygnus.com> + * srcbar.tcl (cancel_download): New method to cancel downloads. Needed + to cancel download dialog-enabled downloads. + (_set_runstop): Call cancel_download. + * download.tcl (Download::constructor): Make sure to set the toolbar + properly so that the Stop/Cancel button cancels a download. + (download_it): Force the CANCEL to all download_progress_hook's. + * src.tcl (download_progress): Add special section identifier for + canceled downloads. + (SrcWin::destructor): Pass the state_hook's command to remove_hook. + + Sean Mahan <smahan@cygnus.com> + * toolbar.tcl (create_menu_items): Help menu follows "Help Topics" + standard (PR 15082). + + Tom Tromey <tromey@cygnus.com> + * interface.tcl (gdbtk_tcl_query): Consolidate Windows case; must + `vwait' even when question is already being asked. + + Martin M. Hunt <hunt@cygnus.com> + * interface.tcl (gdbtk_tcl_query): Only use ide_messageBox + on Windows. + + Martin M. Hunt <hunt@cygnus.com> + * register.tcl: Catch several gdb_register commands + so errors don't bother us. + * variables.tcl (destructor): Remove all hooks. + + Martin M. Hunt <hunt@cygnus.com> + * download.tcl (done): Don't let seconds be zero. + * manage.tcl (manage_disable_all): Don't ever disable "." + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (run_executable): Removed delete_breakpoints + stuff. + * download.tcl (download_it): Removed delete_breakpoints + stuff. Clear any breakpoints at exit and main before + restarting. They get set again automatically if the + preferences say they should. + (Download): Don't call freeze on download window, because + it stops updating when we do. + (update): Renamed to update_download to avoid confusion. + * src.tcl (mode): When changing from SRC+ASM to another + mode, unset "awin". + (bp_line): On a "Continue to Here" don't try to + restore breakpoints that didn't exist before. + + Tom Tromey <tromey@cygnus.com> + * interface.tcl (gdbtk_tcl_query): Set -parent on dialog. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (build_win): Set mode combobox width to 10. + (goto_func): If a function name is an unmangled one, + it is a C++ method so don't prepend filename when + setting location. This is a kludge, but we are limited + by the symtax the GDB command line parser will accept. + (location): When loading function combobox, + remember which names are unmangled. Change width of + function combobox dynamically to better accomodate + those long C++ names. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (bp_line): When doing a "continue to here", + first save states of all breakpoints then restore + when finished. + (config_win): Uncomment "Continue to Here" menu item. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (location): Use ide_cygwin_path on Windows + to change project root to the right format. + + Drew Moseley <dmoseley@cygnus.com> + * main.tcl: (run_executable): Modified to call download_it + with the parameter indicating whether to delete breakpoints. + If GDB is loaded ($gdb_loaded == 1) and the app is running + ($gdb_app_running == 1) then we don't delete the breakpoints. + All other situations will require deleting the breakpoints. + This allows us to redownload and run the same executable w/o + losing the breakpoint information. + * download.tcl: (download_it): Modified this routine to + take a boolean parameter indicating whether to delete + the breakpoints before downloading. + + Sean Mahan <smahan@cygnus.com> + * toolbar.tcl (create_menu_items): Couldn't use 'helpdir' + variable so used Paths(prefix) and added help. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (set_state): Turn off debugging. + (location): Map windows pathnames into form GDB uses + internally. + (bp_line): Use gdb_set_bp to set breakpoints on + a specific line in a file. + + Martin M. Hunt <hunt@cygnus.com> + * stack.tcl (update): Skip over any empty elements + in parsing the stack line to get the correct PC. + + Keith Seitz <keiths@onions.cygnus.com> + * download.tcl (download_it): Run gdb_busy_hook's. + If anything fails, make sure that the no_inferior_hook's are run. + Note errors that occur during downloading, ignoring the + "cancelled download" message. If an error occurs, set the + global gdb_download_error to the error message so that it can + be shown to the user later. Don't run the idle hooks if nothing + * src.tcl (download_progress): Do not rely on the value of + "download_cancel_ok" -- it is cleared in download_it. + Reorder code to take advantage of gdb_loaded and gdb_download_error + to determine if a download was canceled, successful, or failed due + to an error. Truncate the "DOWNLOAD FINISHED:" message so that it + will fit into the status bar given the recent font changes. + (busy): If gdb_loaded, set the status bar to read "Program is running." + Otherwise, don't touch it. + (config_win): Comment out "Continue to here" right-click menu item + until it can properly preserve breakpoint state. + (no_inferior): Configure the toolbar to -runstop 0. All of these + toolbar references should be done via the busy hook by the SrcBar + class itself someday... + + Sean Mahan <smahan@cygnus.com> + * toolbar.tcl (create_menu_items): Added ability to launch + the tour help file from the help menu. + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl, ide.tcl: Disable some debugging messages. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (set_state): When loaded state changes, invalidate + current file. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (SrcWin): Change default title to "Foundry Debugger". + (build_win): Change name and function combobox heights to 0. + Set status bar font to src-font. + (name): Rewrite to use _files array. This array allows us + to map full pathnames with short names that are easily displayed. + (file): Call set_name to update name combobox. + (location): Call set_name to update name combobox. When setting + the function combobox, adjust height to a maximum of 10. CLear + filename combobox if there is no valid filename. When setting the + filename combobox, adjust height to a maximum of 10. Create + _files array mapping full pathnames to short names. For IDE, use + vmake/source-files and project-root to build full pathnames. + When changing mode, save current line. Don't mark current line + with PC_TAG if gdb_running is 0. + (set_name): New function. Update the name combobox, using + the short name from _files if available. + * bp.tcl (bp_modify, bp_add): Use short file name from + _files global array. + + Keith Seitz <keiths@onions.cygnus.com> + * variables.tcl (VariableWin): Add idle, busy, and no inferior hooks. + (selectionChanged): Use Running fencepost. + (updateNow): Use Running fencepost. + (editEntry): Use Running fencepost. + (postMenu): Use Running fencepost. + (setDisplay): Use Running fencepost. + (open): Use Running fencepost. + (close): Use Running fencepost. + (enable_ui): Define new procedure to install fencepost. + (disable_ui): Define new procedure to remove fencepost. + (no_inferior): Define new procedure to remove fencepost and clear tree. + (Running): New protected data. This is used as a fencepost in this object. + * main.tcl: Run gdb_no_inferior_hook's when done initializing. + * src.tcl (disable_ui): Disable the combo boxes, too. + (enable_ui): Enable the combo boxes, too. + * download.tcl (download_it): Run gdb_no_inferior_hooks, too. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl: Move IDE help initialization to ide.tcl. + * ide.tcl (gdbtk_ide_init): Move help system + initialization here. + + Sean Mahan <smahan@cygnus.com> + * main.tcl: Initialized help sub-system for the ide. + + Tomy Hudson <thudson@thudson5.cygnus.com> + * prefs.tcl: Changed COM1 back to com1 per Martins request. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (file): Call gdb_loadfile to do most of the + work. + + Tomy Hudson <thudson@thudson5.cygnus.com> + * prefs.tcl: Changed "com1" to "COM1" + + <dmoseley@cygnus.com> + * main.tcl: (run_executable): Added code to test for app_running. + If the app has been started and the user requests a "run", then + we must redownload to ensure that the global initialized data is + handled properly. + * download.tcl: (download_it): See above note. + + Sean Mahan <smahan@cygnus.com> + * toolbar.tcl (create_menu_items): changed "Tutorial" to "Cygnus + Foundry Tour" in the Help menu. + + Tom Tromey <tromey@cygnus.com> + * memory.tcl (mem_del): "destroy forget" is invalid; use "destroy" + instead. + * interface.tcl (gdbtk_tcl_query): Only ask each question once. + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl (manage_init): Initialize new global + _manage_enabled_flag to 1. + (manage_disable_all): Only disable if + _manage_enabled_flag is 1. + (manage_enable_all): Only enable if _manage_enabled_flag + is not 1. + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl (manage_iconify): Check for toplevel + of "." before doing anything. + * main.tcl (set_target_name): Use "pref getd" in + case port is undefined. + + Keith Seitz <keiths@onions.cygnus.com> + * toolbar.tcl (GDBToolBar::constructor): Add appropriate idle, busy, and + no-inferior hooks for this class. + (create_buttons): Add all buttons to two lists so we can disable or enable + them according to the inferior's run state. + (create_menu_items): Same with the menus. + * srcbar.tcl (create_buttons): Add all buttons to two lists so we can disable + or enable them according to the inferior's run state. + (create_menu_items): Same with the menus. + (_set_run): Don't do anything to disable UI elements: the idle, busy, and + no_inferior hooks will take care of it. + (_set_runstop): Don't do anything to disable UI elements: the idle, busy, and + no_inferior hooks will take care of it. + * manage.tcl (manage): Add two new manage protocols: enable_all and + disable_all. + (manage_disable_all): New procedure to disable window manager functions + such as window deletions. + (manage_enable_all): New procedure to undo any changes made by + manage_disable_all. + (_manage_set_property): New helper procedure for above. + (manage_init): Install this module's idle, busy, and no_inferior hooks. + * src.tcl (SrcWin::constructor): Add new no_inferior hook. + (disable_ui): New procedure to disable ui elements. + (enable_ui): New procedure to enable_ui elements. + (no_inferior): New procedure to reset GUI. + (SrcWin::Running): New protected variable. A fencepost for the above + hooks. + (do_popup): Use above fencepost. + (showBalloon): Use above fencepost. + * main.tcl: Define new hook " gdb_no_inferior_hook". + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (SrcWin): Immediately set title name + to "Debugger". + + Martin M. Hunt <hunt@cygnus.com> + * download_pref.tcl (LoadPref): Make window transient. + + Martin M. Hunt <hunt@cygnus.com> + * register.tcl (build_win): Set scrollbars to auto + on Unix. + * stack.tcl (build_win): Set scrollbars to auto + on Unix. + * memory.tcl (build_win): Restore proper resize + functioning on Unix. + * bp.tcl (build_win): Fix problem with merging Tom's + sizebox change. Fix Tom's change so scrollbars aren't + always on on Unix, at least. + * interface.tcl (gdbtk_pc_changed): Called from GDB when + the PC is changed with a "set $pc" command. + (gdb_show_command, gdb_args, gdb_stack_trace, + gdb_docstring,gdb_stack_depth, gdb_stack_frame): Removed. + + Martin M. Hunt <hunt@cygnus.com> + * memory.tcl (destructor): Destroy memory prefs window + if one exists. + (create_prefs): Make prefs window transient. + * util.tcl (freeze): Make keep_raised an option. + + Martin M. Hunt <hunt@cygnus.com> + * ide.tcl (receive_file_changed): Ignore object file + changes. On source file changes, put up a messagebox + warning the user. Change both messageboxes to be system + modal, which seems to just mean they will be on top. + + Martin M. Hunt <hunt@cygnus.com> + * download.tcl (download_it): Reset download_cancel flag. + * src.tcl: Create "tagtype" as a protected variable + containing the current tag mode; PC, BROWSE, or STACK. + Change all functions to use it. + (mode): Fix problem with changing modes + while browsing stack functions. + (name): Add good filenames to the combobox history. + (SrcWin): Turn off automatic history in name combobox. + (file): If filename is not found, but is part of sources, + put it in combobox followed by "(not found)" + (location): Reorder and restructure this function to + be more robust when files cannot be found or mode changes + are required. When stack browsing, highlight PC if it is + in the displayed area, and fix the off-by-1 problem + with PCs saved on the stack. + (update): Use lassign and new tagtype variable. + (set_execution_status): Change message formats for MIXED + and SRC+ASM modes. + (mode): Update toolbar and mode display before calling + location. Use tagtype so tag mode is preserved. + * bp.tcl (bp_type): Deselect line before changing its + type. + + Tom Tromey <tromey@cygnus.com> + * bp.tcl (build_win): Use built-in sizebox of tixScrolledWindow. + * watch.tcl (console): Set Sizebox to 0. + * memory.tcl (build_win): Use built-in sizebox of + tixScrolledWindow. + * stack.tcl (build_win): Use built-in sizebox of + tixScrolledWindow. + * locals.tcl (build_win): Don't create sizebox. + * variables.tcl (build_win): Use built-in sizebox of + tixScrolledWindow. + (Sizebox): New instance variable. + * console.tcl (console): Use built-in sizebox of + tixScrolledWindow. + * register.tcl (build_win): Use built-in sizebox of + tixScrolledWindow. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (set_target_name): Set port based on target + name. + (set_baud): Set baud rate based on target name. + * srcbar.tcl: Change shortcuts to use () instead of <>. + * download.tcl (download_it): Set download_verbose + based on target name. + * src.tcl (build_win): Set height to 0 for name and + function comboboxes. + (location): In IDE, use vmake/source-files property + to fill name combobox. + + Keith Seitz <keiths@onions.cygnus.com> + * variables.tcl (build_win): Set the variable window's + default size to 40 chars. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (set_state): When loaded state changes, + set program_has_run state to 0. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (set_status): Rewrite to handle temporary + status messages. + (set_execution_status): New function. Put a message + about the current program status in the status bar. + (trace_help): New function. Trace on changing ballon + help messages. Write them in the status bar. + * main.tcl (set_target): Comment out changing cursor. + + Martin M. Hunt <hunt@cygnus.com> + * variables.tcl (changeValue): Trim string before + comparing with "". + + Keith Seitz <keiths@onions.cygnus.com> + * console.tcl (constructor): Set no wrap mode. + * src.tcl (SrcWin::name): Make sure we ask gdb where the source file + is before asking the source window to open it. + (SrcWin::file): Do not ask gdb where the file is -- someone else + already has. Set the file selector to the filename only once and + only if successful finding the file. + (SrcWin::location): Add flag idicating that a file load has failed. + Resolves recursive loop with SrcWin::mode and SrcWin::location. + Make sure the file and function selectors are filled only once. + (SrcWin::mode): Add error flag to indicate that a file load failed. + Resolves recursive loop with SrcWin::location. + Make sure we exit with the proper mode set on the source window. + (SrcWin::current_addr): Define a default value of 0x0. + * console.tcl (invoke): Use new gdb_immediate command instead of + gdb_cmd. + (insert): Add all errors to the end of the text widget. + Send errors to end of text widget, not insertion pt. + (einsert): Send errors to end of text widget, not insertion pt. + * interface.tcl (gdbtk_tcl_readline_begin): Insert message into + command window so that the user sees messages like "Enter commands, + one per line. Enter 'end' when finished." + * main.tcl: Initialize gdbtk_state(readline). + + Tom Tromey <tromey@cygnus.com> + * manage.tcl (manage_open): Force focus onto toplevel. + * mem_pref.tcl (build_win): Don't put <Return> binding on + toplevel; instead put focus on OK button. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (set_target_name): Replace "com1" with + the port name we really want to use. + * bp.tcl (build_win): Use place manager for sizebox + so it doesn't go away when window is resized. + * stack.tcl (build_win): Fix stack window. + * memory.tcl: Back out previous changes. + * locals.tcl (build_win): Use place manager for sizebox + so it doesn't go away when window is resized. + + Tom Tromey <tromey@cygnus.com> + * mem_pref.tcl (build_win): Make OK button default. + * ide.tcl (gdbtk_ide_init): Set gdb_pretty_name. Track changes to + target-pretty-name property. + * src.tcl (update_title): Display pretty name for target. + * main.tcl (set_target): Display pretty name for target. + (gdb_pretty_name): New global. + * ide.tcl (target_pretty_name_changed): New proc. + (receive_file_changed): Display pretty name for target. + * download.tcl (download_it): Display pretty name for target. + (console): Likewise. + + Thomas Hudson <thudson@cygnus.com> + * bp.tcl (build_win): Added frame and sizebox to bottom. + Returned geometry management to previous packing style + and window layout. + * stack.tcl (build_win): ditto + * memory.tcl (build_win): ditto + * watch.tcl (build_win): ditto + * locals.tcl (build_win): ditto + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl (manage_iconify): Catch iconify command. + * download.tcl (download_it): If set_target fails, + set gdb_downloading to 0 and return. + * main.tcl (set_target): Handle target command timeouts. + Pop up messagebox. Set cursor to "watch". Set title + on source window. Return 0 on error. + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl (manage_find): Fix to return a list of windows. + * console.tcl (Console): Fix sizebox so it doesn't create + a whole blank line and it doesn't mess up Unix. + * register.tcl (build_win): Change "Show" to "Display". + + Tomy Hudson <thudson@cygnus.com> + * console.tcl (build_win) Added frame and ide_sizebox to + bottom of window. + * stack.tcl (build_win) Added frame and ide_sizebox to + bottom of window. + * watch.tcl (build_win) Added frame and ide_sizebox to + bottom of window. + * locals.tcl (build_win) Added frame and ide_sizebox to + bottom of window. + + Tom Tromey <tromey@cygnus.com> + * memory.tcl (build_win): Updated -underline values. + + Martin M. Hunt <hunt@cygnus.com> + * memory.tcl (init_addr_exp): New function. Set the + initial address expression to the location of .data + if it is defined. Otherwise use $pc. + + Tom Tromey <tromey@cygnus.com> + * bp.tcl (build_win): Changed packing so content fills window. + Removed `g' and `a' frames. Changed gridding on labels. + (bp_add): Changed gridding on new entries. + * memory.tcl (build_win): Put spaces in front of all menu labels. + + Martin M. Hunt <hunt@cygnus.com> + * download.tcl (download_it): Change error to messagebox. + + Tom Tromey <tromey@cygnus.com> + * register.tcl (reg_display_list): Initialize to empty list. + (init_reg_display_vars): Don't unset reg_display_list; set it to + empty list. + (delete_from_display_list): Likewise. + + Martin M. Hunt <hunt@cygnus.com> + * ide.tcl (ide_run_server, ide_do_run_server): Take + an optional argument to indicate if program should be + run or simply downloaded. + * console.tcl (Console): Enable scrollbars in both + directions. + * main.tcl: Moved keep_raised, sleep, and toggle_debug_mode + to util.tcl. + (set_exe): If exe changed, set gdb_target_changed + to force new target command to be sent. + (set_target_name): Check to see if gdb_target_changed. + (run_executable): If exe or target changed, set gdb_loaded to + 0, forcing a new download. If download only, try to + display function main in source window. + * util.tcl: New file. + * hooks.tcl: Removed. Use version in libide. + * Makefile: Add util.tcl. + * download.tcl (Download): Call freeze to make modal window. + (_map): Deleted. + (download_it): Call set_baud, then set_exe then set_target. + * mem_pref.tcl (build_win): Set default number of bytes + to 128. + * memory.tcl (build_win): Enable horizontal scrollbar + when in resize mode. Anchor to top-left. Use "nb" to + count actual number of bytes displayed, instead of "numbytes" + which will be 0 when in resize mode. + (delete_prefs): Deleted. + * src.tcl (mode): Update mode combobox with new mode name. + (location): In SRC+ASM mode if we step into a function without + source code, unhighlight everything in the source pane and let + the assembly pane show our current location. + (build_win): Enable scrollbars in both directions. + (set_state): Call update_title. + (update_title): Don't set title if the target or exe has changed. + (trace_variable): Couldn't figure out what this did that + could be useful so delete it and everything that references it. + * watch.tcl: Add description and copyright. + * variables.tcl, interface.tcl, locals.tcl: Add copyright. + * prefs.tcl, register.tcl: Add copyright. + + Tomy Hudson <thudson@cygnus.com> + * register.tcl (reg_select_): Modified reg_select_* movement + methods to use the register display list instead of + a straight index. + + Tomy Hudson <thudson@cygnus.com> + * register.tcl (unedit): Changed input focus to $ScrolledWin.$Editing + in unedit. This allows arrow and tab key bindings to work + after an edit. + + Tomy Hudson <thudson@cygnus.com> + * register.tcl (build_win): Added key bindings and support + for tab and arrow keys, including four new methods; + reg_select_up,reg_select_down, reg_select_left, reg_select_right + * register.tcl (build_win): Added spacing frame and ide_sizebox + to window. Changed geometry manager to grid. + + Martin M. Hunt <hunt@cygnus.com> + * stack.tcl (update): Only insert entries that have + length. Break when matching entry in listbox is found. + * src.tcl (config_win): Fix control-v binding so + it doesn't paste on Windows. Cancel <Delete> + binding. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (build_win): Force focus from toplevel + down to text window. + (mode): Restructure code to be clearer. Set focus + when done. + + Tomy Hudson <thudson@cygnus.com> + * src.tcl (mode): Modified key bindings for MIXED mode + to be the same as ASSEMBLY mode + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl (manage_init): set bp-save to 1. + * variables.tcl (changeValue): If new value is null, + cancel edit. + + Tomy Hudson <thudson@cygnus.com> + * memory.tcl (do_popup): Added method do_popup. Changed binding of + button-3 to invoke popup menu. + + Tomy Hudson <thudson@cygnus.com> + * src.tcl (do_popup): Removed check for space in variable name + that disabled popup menu items. Only check now is for "". + + Tomy Hudson <thudson@cygnus.com> + * src.tcl (do_popup): Removed variable name from + popup menu items. Added check for sane variable in selection + to disable menu items when appropriate. + + Martin M. Hunt <hunt@cygnus.com> + * bp.tcl (bp_delete): Destroy widgets in deleted + line. + * srcbar.tcl (_set_run): Enable View menu items + when download is finished. + * download_pref.tcl (LoadPref): Call loadprefs + with gdbrunning set to 1. + + Tom Tromey <tromey@cygnus.com> + * ide.tcl (gdbtk_ide_init): Use property vmake/exelist, not + vmake-exelist. + + Martin M. Hunt <hunt@cygnus.com> + * variables.tcl (build_menu_helper): Comment-out + Update menu. + (getVariables): Change variable name so it doesn't + get confused with window variables. + (postMenu): Comment-out Update entries. + (UnEdit): Unbind keys when unediting. + * memory.tcl (create_prefs): When prefs are already + open, raise and focus the window. + * bp.tcl (bp_type): Deselect current line when type changes. + + Martin M. Hunt <hunt@cygnus.com> + * toolbar.tcl (create_menu_items): Call open_url for + web connections. + * src.tcl (name): When new file load fails, remove it + from combobox. When load succeeds, clear status message. + (location): Change how files are loaded into combobox. + Call new gdb_listfiles function. + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl (manage_create): Give newly created windows + the focus on all platforms. + * mem_pref.tcl (destructor): Notify parent when exiting. + * srcbar.tcl (_set_run): Better state handling on + pulldowns and icons. + * src.tcl (build_win): Start with toolbar in right state. + * memory.tcl (MemWin): Withdraw window until finished. + (delete_prefs): New function. + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl: For IDE, iconify all windows when source + window is iconified. + * mem_pref.tcl: Take out all the modal stuff. + Leave this window non-modal. + * download.tcl: Fix references to source window. + (Download): Make window modal and always on top. + * memory.tcl (destructor): Kill mem prefs window too. + * variables.tcl (changeValue): Clean up. + * register.tcl (acceptEdit): Change error messagebox. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (set_state): Disable items in breakpoint + popups. + (config_win): Change capitalization in popups. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl: Major rewrite. Simplify. Move IDE + functions to new file. Add state variables and + hooks. Add copyright. + * ide.tcl: New file. IDE functions. + * download.tcl (download_it): Use new state variables. + * src.tcl: Use new state variables. + (constructor): Add state hook. + (set_state): Hook to enable/disable menus and icons. + * srcbar.tcl (runstop): Renamed from "running" + (running): Public variable to control icons. + (_set_runstop): Change Running man to stop sign. + (_set_run): Enable/disable icons depending on debugger + state. + * manage.tcl (create_closed): Deleted function. + (manage_create): Remove visibility argumnet. + (manage_delete): Remove special case for debugger prefs. + * prefs.tcl (pref_set_defaults): Remove gdb/advanced. + * hooks.tcl: Add copyright. + * Makefile: Add ide.tcl. + + Tom Tromey <tromey@cygnus.com> + * download_pref.tcl (LoadPref): Inherit from GdbLoadPref. + (constructor): Rewritten. + (build_win): Removed. + (change_baud): Removed. + (save): Removed. + (cancel): Removed. + (config): Removed. + (reconfig): Removed. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (target_name_changed): Append correct + port name to target name. + (gdbtk_ide_init): Don't initialize IDE preferences. + Append port name to target name. + * toolbar.tcl (create_menu_items): Add Debugger Preferences + to File menu. + * pref.tcl: Remove all ide preferences functions. + * prefs.tcl (pref_set_defaults): Define gdb/load/port. + * download_pref.tcl: Added serial port selection. + + Martin M. Hunt <hunt@cygnus.com> + * register.tcl (acceptEdit): Remove leading spaces from + values. + * src.tcl (config_win): New tag bp_tag. Like break_tag + except used when a bp is set on that line. Bind new menu + to bp_tag. + (insertBreakTag): Accept tag type. Remove old tag. + (do_bp): When a breakpoint is set, use bp_tag. + + Tom Tromey <tromey@cygnus.com> + * pref.tcl (pref_ide_proc): Withdraw the toplevel, not the + window. + + Tom Tromey <tromey@cygnus.com> + * tclIndex: Rebuilt. + * mem_pref.tcl (build_win): Use standard_button_box. + (_map): New method. + (constructor): Run _map on <Map> event. + * pref.tcl (pref_ide_proc): Use idewindow_check_freeze. + (pref_modal_dialog): Use idewindow_freeze and idewindow_thaw. + * hooks.tcl: Removed. + * Makefile (TCL): Removed hooks.tcl. + + Tom Tromey <tromey@cygnus.com> + * main.tcl (ide_run_server): Quote call to ide_do_run_server. + + Tom Tromey <tromey@cygnus.com> + * download_pref.tcl (build_win): Make OK button default. Invoke + when Return pressed. + * download_pref.tcl (build_win): Don't allow pref window to + resize. Use standard_button_box to lay out buttons. + * pref.tcl (pref_ide_proc): Handle window freezing. + (pref_modal_dialog): Freeze and thaw window around the grab. + (build_win): Use standard_button_box to lay out buttons. Don't + allow pref window to resize. + + Ian Lance Taylor <ian@cygnus.com> + * src.tcl (src_ide_proc): Download the file in an idle callback. + Execute the idewindow command even if the download was cancelled. + * library/main.tcl (ide_run_server): Do everything in an idle + callback. + (ide_do_run_server): New procedure. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl (bp_line): Use hasBP instead of validBPLine. + Allow type TC even if BP set. + (validBPLine): Renamed to hasBP. + + Tom Tromey <tromey@cygnus.com> + * manage.tcl (manage_open): Special case "about" window when + running under IDE. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (set_target): Set the target again if the + executable has changed and executed a "file" command. + * memory.tcl (update_address): Accept numerical entries + and catch errors. + * download.tcl (Download): Cancel button should call + cancel method. + * main.tcl (run_executable): Fixed messageBox. + + Tom Tromey <tromey@cygnus.com> + * floatbar.tcl (constructor): Added. + * srcbar.tcl (constructor): Added. + * toolbar.tcl (_ide_title): New instance variable. + (create_menu_items): Pass _ide_title to idewindmenu. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (toggle_debug_mode): Fix typo and print + debug message before disabling it. + + Martin M. Hunt <hunt@cygnus.com> + * manage.tcl (manage_delete): Don't remove a window + from the active list until after it has already deleted + itself. + * toolbar.tcl (create_menu_items): Change Console shortcut + to Ctrl+N. + * src.tcl (config_win): Change Console shortcut to Ctrl+N. + + Martin M. Hunt <hunt@cygnus.com> + * src.tcl: (do_bp): Catch errors. + (validBPLine): Valid lines have a "-" or an image. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (ide_run_server): Don't run executable if + download was cancelled. Reset cancelled flag. + (run_executable): Call download_it. + (download): Renamed download_it and moved to download.tcl. + (set_target): Don't set target if the name hasn't changed + from the last time. + * register.tcl (reg_select): Catch errors. + (delete_from_display_list): Enable menu item. + * src.tcl (build_win): Add progress bar for downloads. + (download_progress): New function. Callback to update + progress meter. + (src_ide_proc): Don't open src window if download + cancelled. + * toolbar.tcl (create_menu_items): Call download_it. + * srcbar.tcl (_set_run): New mode. Sets run button to stop + sign during downloads. + * prefs.tcl (pref_set_defaults): Define gdb/load/verbose. + * interface.tcl: Define new hook download_progress_hook. + * floatbar.tcl (create_buttons): Call download_it. + * download_pref.tcl: Add download dialog prefs. + * download.tcl (Download): Change back to old dialog + with each section listed seperately. + (download_hash): Use a hook. + (download_it): New function. Replaces old "download" + from main.tcl. Now deletes all breakpoints before + downloading and handles cancels correctly. + + Martin M. Hunt <hunt@cygnus.com> + * main.tcl (download): Don't quote the executable name + with single quotes. + + Tom Tromey <tromey@cygnus.com> + * src.tcl (src_ide_proc): Exit gdb when destroy request seen. + + Ian Lance Taylor <ian@cygnus.com> + * main.tcl (gdbtk_ide_init): Use src_ide_proc for the source + window, rather than idewindow_proc. Remove extraneous line. + * src.tcl (src_ide_proc): New procedure, replacing open_src. Only + download if we are opening the source window. + (src_no_save): New procedure. + * main.tcl (gdbtk_ide_init): Initialize gdb_checking_for_exit. + Register gdb_exit_check as the exit check procedure. + (gdb_exit_check): New procedure. + * interface.tcl (gdbtk_tcl_query): If gdb_checking_for_exit, use a + system modal message box. + * src.tcl (build_win): Create a FocusIn binding to push focus down + from the top level. + * console.tcl: Change all control, alt, and unadorned character + bindings to use bind_plain_key. + * memory.tcl: Likewise. + * src.tcl: Likewise. + * variables.tcl: Likewise. + * src.tcl: Use bind_plain_key rather than explicitly ignoring Alt + bindings. + * src.tcl (print): Call idewindow_freeze and idewindow_thaw around + call to print menu. + * srcbar.tcl (create_menu_items): Likewise, around call to page + setup menu. + * main.tcl (gdbtk_ide_init): Use an underscore in generic window + name, to set the accelerator key. + (ide_run_server): Likewise. + * toolbar.tcl (create_buttons): Likewise. + + Martin M. Hunt <hunt@cygnus.com> + * register.tcl (acceptEdit): If no value is entered, + set the cell to 0. + + Ian Lance Taylor <ian@cygnus.com> + * src.tcl (config_win): Add ignored Alt bindings for all the + unmodified key bindings. + * download.tcl (constructor): Withdraw the window before doing + anything. Set the width of the label. Don't try to center the + window. Pass toplevels to wm transient. Run keep_raised after + 500. Don't call update. + (done): Use after rather than a busy loop. + (destructor): Cancel the after if it is defined. + (after_id): New protected variable. + * main.tcl (download): If download is already running, don't do + anything. If .load0.load exists, delete it before calling manage + create. + * main.tcl (gdbtk_ide_init): Use pref_ide_proc rather than + idewindow_proc when registering the preference window. + * download_pref.tcl (save, cancel): Call pref_ide_finished. + * pref.tcl (save, cancel): Likewise. + (pref_ide_proc): New procedure. + (pref_no_save): New procedure. + (pref_modal_dialog): New procedure. + (pref_ide_finished): New procedure. + * tclIndex: Rebuild. + * main.tcl (gdbtk_ide_init): Initialize gdb_download_cancelled. + (run_executable): Put a trace on gdb_download_cancelled. Change + the dialog box message. If the user cancels the download, clear + gdb_run_pending and just return without running. + (ide_do_run): Remove the traces on gdb_download_cancelled. If the + user cancelled the download, just clear gdb_run_pending. + (target_name_changed): Clear gdb_download_cancelled. Call + set_exe_name. + (download): If the executable is not up to date, ask whether the + user is really really sure. If the user cancels the download + using the dialog button, set gdb_download_cancelled, and don't set + the breakpoints or gdb_download_complete. + (set_exe_name): Clear gdb_download_cancelled. + (receive_file_changed): Ask whether we should download the new + executable. + * src.tcl (open_src): Don't download the file if + gdb_download_cancelled is set. + * interface.tcl (gdbtk_tcl_query): Pass -modal task to + tk_messageBox. + * main.tcl (set_exe_name): Tell the src window to go back to + looking at main if the file changes. + * src.tcl (update): Catch errors when calling gdb_loc. + * main.tcl (gdbtk_ide_init): Handle file-created, file-changed, + file-removed, and file-deleted events rather than process-ended + events. + (set_exe_name): Call gdb_clear_file even if the file does not + exist. Likewise for setting gdb_download_complete to zero. + (receive_file_changed): Rename from receive_process_ended. Only + check the executable mtime if the tail of the file name matches + the executable name. + + Ian Lance Taylor <ian@cygnus.com> + * srcbar.tcl (create_menu_items): Change ``Print Setup...'' to + ``Page Setup...''. Pass -parent to ide_winprint page_setup. + * src.tcl (print): Pass -parent to send_printer. + + Ian Lance Taylor <ian@cygnus.com> + * main.tcl: Move initialization code to end of file, after all + procedures have been defined. + (gdbtk_ide_init): New procedure to handle IDE initialization. + (gdbtk_tcl_preloop): Don't do anything if using the IDE. + (ide_run_server): Error if file does not exist. Use + idewindow_activate_by_name, rather than manage open. Do + everything after idle. + (run_executable): Clean up a bit. Consistently use ide_do_run. + (target_name_changed): Rename from target_name. Rename parameter + num to propset. + (download): Error if the file does not exist. Call set_exe_name. + Don't set gdb_download_mtime. Don't check whether gdb_run_pending + is 2. + (exe_name_changed): Rename from exe_name. + (set_exe_name): Set gdb_exe_mtime. Quote filename passed to + gdb_cmd. + (receive_process_ended): Don't check the data argument. Check + gdb_exe_set rather than gdb_download_complete. Check + gdb_exe_mtime rather than gdb_download_mtime. + * src.tcl (open_src): Set the location to main as well as + downloading the file. Don't set gdb_run_pending to 2. + + +Tue Feb 10 17:50:37 1998 Keith Seitz <keiths@onions.cygnus.com> + + * bp.tcl (build_win): Do not set the disabled foreground for menus. Insert + all tracepoints, too. + (bp_add): Handle tracepoints. + (bp_type): Handle tracepoints. + (update): Handle tracepoints. + (bp_all): Do tracepoints, too. + (Index_to_bptype): New protected variable to index type of break (breakpoint + or tracepoint) against index in window. + (bp_select): Disable/Enable menu items based on type. + (bp_able): Handle tracepoints. + + * src.tcl (do_bp): Handle disabled tracepoints. + + * actiondlg.tcl (change_other): Handle memranges and use info address to + validate entries. + + * tracedlg.tcl (edit): Handle memranges when formatting data for + action dialog. + +Mon Jan 26 11:44:39 1998 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (fill_files): Don't check for file's existance -- let + SrcWin::name do that. + + * actiondlg.tcl (change): Add everything that is specified, not + just the things about which we know. + +Sun Jan 25 01:01:32 1998 Martin M. Hunt <hunt@cygnus.com> + + * stack.tcl (update): Only insert entries that have + length. Break when matching entry in listbox is found. + + * src.tcl (fill_files): Don't call lsort. New listfiles + command sorts for us. + + * variables.tcl (changeValue): If new value is null, + cancel edit. + (build_menu_helper): Comment-out Update menu. + (getVariables): Change variable name so it doesn't + get confused with window variables. + (postMenu): Comment-out Update entries. + (UnEdit): Unbind keys when unediting. + +Thu Jan 22 10:38:19 1998 Keith Seitz <keiths@cygnus.com> + + * toolbar.tcl (create_menu_items): Disable preferences. + + * prefs.tcl (pref_set_defaults): Attach the toolbar to the source window + by deafult. + * src.tcl (SrcWin::build_win): Turn off history for the file selector. + (SrcWin::name): Use SOURCEWIN_set_status to upate status. + Make sure we ask gdb where the source file is before asking + the source window to open it. + (SrcWin::file): Do not ask gdb where the file is -- someone else already has. + Set the file selector to the filename only once and only if + successful finding the file. + (SrcWin::fill_files): Sort the files before inserting into file selector. + (SrcWin::location): Add flag idicating that a file load has failed. Resolves + recursive loop with SrcWin::mode and SrcWin::location. + Make sure the file and function selectors are filled only once. + Use SOURCEWIN_set_status and SOURCEWIN_reset_status as appropriate. + (SrcWin::set_status): Add verbatim flag to allow a generic message to be + displayed. + (SrcWin::mode): Add error flag to indicate that a file load failed. Resolves + recursive loop with SrcWin::location. + Make sure we exit with the proper mode set on the source window. + (SrcWin::reset_status): New procedure. + (SrcWin::current_addr): Define a default value of 0x0. + (SrcWin::Status): New protected variable. + (SrcWin::bp_line): Check if breakpoint set in assembly-mode, too. + (SOURCEWIN_set_status): New procedure to temporarily set the status bar. + (SOURCEWIN_reset_status): New procedure which is called after the status bar + should be reset. + (SOURCEWIN_reinit): New procedure to reinitialize the source window. (To be + called when new symbol files are added and like). + + * interface.tcl (gdbtk_tcl_query): Properly set the name of the + query dialog. + (gdbtk_tcl_pre_add_symbol): Hook called from gdbtk.c to inform user that + we are reading symbols. + (gdbtk_tcl_post_add_symbol): Hook called from gdbtk.c to inform user that + are finished reading symbols. + + * src.tcl (SOURCEWIN_reinit): New procedure which updates the source window with + a default file, fills the file selectors, etc. + (SOURCEWIN_set_status): New procedure which can be used to set the status bar + on the source window. + (set_status): Add flag for setting the status as-is. + + * main.tcl: Call SOURCEWIN_reinit to setup the source window on startup. + + +Fri Jan 16 09:11:30 1998 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (SOURCEWIN_set_status): New procedure to allow anyone to set the + status bar text at the bottom of the source window. + (fill_files): Use a little more full-proof method (if slower) for eliminating + duplicates int the files combobox. + + * interface.tcl (gdbtk_tcl_pre_add_symbol): New procedure called prior to + a symbol file is loaded. + (gdbtk_tcl_post_add_symbol): New procedure called after a symbol file is + loaded. + +Thu Jan 15 12:41:27 1998 Keith Seitz <keiths@onions.cygnus.com> + + * console.tcl (invoke): Use new gdb_immediate command instead of gdb_cmd. + +Wed Dec 31 16:50:26 1998 Keith Seitz (keiths@onions.cygnus.com) + + * actiondlg.tcl (change): handle '$' in register names. + +Wed Dec 10 13:17:21 1997 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (file): Insert tracepoint dots into the source window, too. + + * tracedlg.tcl (build_win): Add an update to workaround a Tix/Tk bug when + mapping the dialog under X. + + * console.tcl (insert): Add all errors to the end of the text widget. + (einsert): Send errors to end of text widget, not insertion pt. + (invoke): Send errors to end of text widget, not insertion pt. + + * interface.tcl (gdbtk_tcl_readline_begin): Insert message into + command window so that the user sees messages like "Enter commands, one + per line. Enter 'end' when finished." + + * actiondlg.tcl (change_other): Clear the entry on <Return>. + Add fencepost to avoid manipulating collect list twice which + could otherwise have undesired side effects. + Add some validation test for typed-in entries. + (ok): Call change_other to check the "Other" entry widget when the + dialog is dismissed. + (change): fix typo + +Mon Dec 8 15:07:51 1997 Keith Seitz <keiths@onions.cygnus.com> + + * tracedlg.tcl (get_data): New method which gets the data associated + with an action. + (add_all_actions): Use the new get_data method. + + * actiondlg.tcl (get_selections): Add "declaration" for i so that + its scope is not limited to for loop. + +Fri Dec 5 10:01:24 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * tracedlg.tcl (build_win): Add support for ranges of lines at which + tracepoint should be set. + (add_action): With ranges, use actions from first in tracepoint in the + range. + (ok): Set tracepoints for ranges, asking if it is ok to overwrite + any existing ones when necessary. Dismiss the dialog first -- or else + it could hang around forever. + (edit): With ranges, use actions of the first tracepoint. + TraceDlg::Lines: Renamed from TraceDlg::Line. + TraceDlg::New: New protected variable (indicates if there are any new + tracepoints being set with this dialog). + TraceDlg::Exists: New protected variable (indicates if there are any + existing tracepoints that may be overwritten -- so ask the user first). + + * src.tcl (fill_files): Use gdb_find_file to test for the existence + of a file, not "file exists". + (do_popup): Filter the selection a little. If the selection is + multi-line selection, enable the tracepoint range option. Don't + display "add to watch" for EVERYTHING! + (validBPLine): Valid lines can have images on them, too. + (bp_line): Fallout of above: check if breakpoint exists before + deciding whether to clear it or set it. + (getVariable): Sllow LINE to be passed, so others can filter lines, too. + (set_tracepoint): Pass TraceDlg a list of lines -- only one line in this + case. + (tracepoint_range): New function to set tracepoint ranges. + (file): Use gdb_find_file to get the real filename. + +Wed Nov 26 15:02:43 1997 Keith Seitz <keiths@onions.cygnus.com> + + * balloon.tcl, gettext.tcl: Remove obsolete files. + + * console.tcl (invoke): Remove debug line. + + * src.tcl (update): Remove debug line. + + * prefs.tcl (pref_set_defaults): Turn debug mode off by deafult. + +Wed Nov 26 11:30:49 1997 Keith Seitz <keiths@onions.cygnus.com> + + * main.tcl: Initialize gdbtk_state(readline). + + * console.tcl (invoke): Check if we are in readline mode, so that + we wait for the user's input and set a global with the result. + (activate): Add prompt argument for readline's prompt. + (setprompt): Add prompt argument for readline's prompt. + + * interface.tcl (gdbtk_tcl_readline): hack to get readline working + + * lots: Merge with foundry's 11/18/97 build. + + * console.tcl (setprompt): Get prompt from gdb. + + * prefs.tcl (pref_set_defaults): Add tracepoint defaults. + + * interface.tcl (gdbtk_tcl_tracepoint): New function which mimicks + gdbtk_tcl_breakpoint. + + * src.tcl (constructor): Set default behavior of left click. Make + a tracepoint dot, too. + (fill_files): "New" function: ripped out of "location". It fills the + 'files' combo box on the bottom of the source window. + (location): Use fill_files to fill the files combo box. + (do_bp): Add support for tracepoints. + (bp_line): Add support for tracepoints. + (set_tracepoint): New function to set a tracepoint on a given line. + (config_win): Add "Set tracepoint here" to right-click menu. + + * actiondlg.tcl: New file to help with tracepoint data collection actions. + + * tracedlg.tcl: New file to help with tracepoints. + +Mon Nov 17 16:49:56 1997 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (config_win): Remove stray character. + +Mon Nov 17 16:04:08 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl (startup code: Use the first element from the + vmake-exelist list. + (exe_name): Likewise. + (gdbtk_tcl_preloop): Quote file name passed to file. + (download): Quote file name passed to load. + +Sun Nov 16 18:21:57 1997 Martin M. Hunt <hunt@cygnus.com> + + * bp.tcl (build_win): Change headers to be raised. + Change resizing so that the bp grid doesn't change + size and is always in the upper left corner. Scrollbars + will appear if the window is shrunk too small. + (bp_add): Set checkbutton color differently if not + on Windows. + + * manage.tcl (manage_init): About title should only + have Foundry in it if we are running Foundry. + +Fri Nov 14 11:15:29 1997 Jeff Holcomb <jeffh@cygnus.com> + + * manage.tcl (manage_init): About window title is now "About + Cygnus Foundry". + + * toolbar.tcl (create_menu_items): Changed "About Foundry + Debugger..." menu option to "About Cygnus Foundry...". + +Fri Nov 14 00:00:42 1997 Martin M. Hunt <hunt@cygnus.com> + + * memory.tcl (toggle_enabled): Toggle the background + color when Auto Update is changed. + + * download_pref.tcl (save): New method. Save new + defaults. + + * pref.tcl (build_win): Don't delete subwidget. + (save): New method. + + * manage.tcl (manage_init): Change preferences title. + + * prefs.tcl (pref_set_defaults): Define gdb/advanced. + Used for testing advanced features. + + * src.tcl (build_win): Set min size for top pane. + (mode): Set minimum size for pane2 when needed. + + * toolbar.tcl (create_menu_items): Underline the + W in "Web", not the "e". + +Thu Nov 13 16:07:53 1997 Jeff Holcomb <jeffh@cygnus.com> + + * download.tcl (done): Update window and show the window for + at least 3 seconds. + (constructor): Initialize start_time and last_num. + +Thu Nov 13 18:17:07 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl (ide_run_server): Call run_executable. + (run_executable): New procedure, mostly from old ide_run_server. + If ! GDBTK_IDE, just execute a run command. In the case where + we've already downloaded, don't bother to do the run command after + idle. If downloading is not forced, ask whether we should do it. + * src.tcl (config_win): Call run_executable, not gdb_cmd run. + * srcbar.tcl (_set_run): Likewise. + * toolbar.tcl (create_menu_items): Likewise. + + * main.tcl: Initialize gdb_exe_set. If IDE, arrange to receive + process-ended events. + (gdbtk_tcl_preloop): Don't try to read the file if it doesn't + exist. + (download): Don't try to download the file if it doesn't exist. + Set gdb_download_mtime. + (exe_name): Just call set_exe_name. + (set_exe_name): New procedure. Like old exe_name, but call + gdb_clear_file before running gdb file command, set gdb_exe_set, + and run gdb_idle_hook. + (receive_process_ended): New procedure. + +Thu Nov 13 13:35:32 1997 Martin M. Hunt <hunt@cygnus.com> + + * prefs.tcl (pref_set_defaults): Set debug off by default. + + * src.tcl (config_win): Bind Ctrl+P and Ctrl+D. + (update_title): Change window titlebar. + + * srcbar.tcl (_set_run): Change balloon help for + stop and run icons. + (create_menu_items): Add accelerator for Print Source. + + * toolbar.tcl (create_buttons): Change balloon help for + project icon. + (create_menu_items): Change access keys. Add accelerator + for Download. + +Thu Nov 13 10:47:04 1997 Jeff Holcomb <jeffh@cygnus.com> + + * download.tcl (constructor): Fix text and button layout. + Don't allow resizing. + +Wed Nov 12 16:59:17 1997 Jeff Holcomb <jeffh@cygnus.com> + + * download.tcl (constructor): Patch from Ian to redo the + download window and also cancel support. + (update): Ditto. + (done): Ditto. + (cancel): New method to handle canceling the download. + (download_hash): Cancel support. + +Wed Nov 12 13:11:20 1997 Martin M. Hunt <hunt@cygnus.com> + + * memory.tcl (build_win): Change "Address" to "Addresses" + on menu and add separator. + +Tue Nov 11 11:00:25 1997 Martin M. Hunt <hunt@cygnus.com> + + * download_pref.tcl (cancel): Must reset combobox + because dialog no longer gets deleted. + +Tue Nov 11 15:40:36 1997 Tom Tromey <tromey@cygnus.com> + + * toolbar.tcl (create_menu_items): Underline "W", not "C", in + "Cygnus on the Web". + +Tue Nov 11 11:00:25 1997 Martin M. Hunt <hunt@cygnus.com> + + * variables.tcl (edit): Disable menus when in editing mode. + +Tue Nov 11 02:00:25 1997 Martin M. Hunt <hunt@cygnus.com> + + * variables.tcl (selectionChanged): When selection changes, + cancel any editing in progress. + (build_win): Set background in text styles. + (edit): Set background colors. + (UnEdit): Clear selection when done. + +Mon Nov 10 12:22:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * variables.tcl (build_win): Set background color. + +Mon Nov 10 05:30:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * about.tcl (build_win): Bind button one to close + the window. + + * tclIndex: Rebuilt. + +Mon Nov 10 03:00:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * download_pref.tcl (build_win): Fix reading of initial + baud rate. + + * download.tcl (Download): Call keep_raised. + + * main.tcl (ide_do_run): Catch GDB commands. + (ide_run_server): Catch GDB commands. + (ide_do_run): Don't set gdb_download_complete to 0. + We don't need further downloads unless executable changes + or Download is selected from the menubar. + (keep_raised): Keep a window on top. + + * src.tcl (config_win): Catch GDB commands. + + * toolbar.tcl (create_menu_items): Catch GDB commands. + (create_menu_items): Remove automatic step. + + * srcbar.tcl (_set_run): Catch GDB commands. + + * stack.tcl (build_win): Change background color. + + * bp.tcl: Change background color. + (destructor): Remove breakpoint change hook. + (bp_type): Fix problem with toggling temp to normal bps. + (build_win): Add popup menu. + + * interface.tcl (gdbtk_tcl_query): Change title and type. + +Mon Nov 10 00:26:25 1997 Martin M. Hunt <hunt@cygnus.com> + + * pref.tcl (build_win): OK button wasn't working. + + * main.tcl: Rework all the "automatic" downloading stuff so + it doesn't download and run when only the preferences are + being displayed. + + * src.tcl (open_src): Callback from IDE that opens + a source window when the bug is clicked on. Starts + up automatic download if necessary. + + * tclIndex: Rebuilt. + + * images2/bp.gif, stack.gif, up,gif, down.gif, bottom.gif: + Updated icons. + +Sun Nov 9 19:30:33 1997 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (gdbtk_tcl_preloop): Remove uneeded if statement. + Remove calls to manage get_state. + + * manage.tcl (manage_get_state): Remove. + (manage_init): Add save state to several windows. + (manage_create): Use ide_property instead of prefs to find window + geometry. + (manage_delete): Restructure to fix several bugs. + (manage_save): Use ide_property instead of prefs. Don't + call pref_save. + (manage_register_defaults): Remove calls to manage_get_state. + + * tclIndex: Rebuilt. + +Sun Nov 9 16:34:44 1997 Tom Tromey <tromey@cygnus.com> + + * pref.tcl (build_win): Removed View page. + + * toolbar.tcl (create_menu_items): Debugger -> "Foundry Debugger"; + Help menu now parallels vmake. + * manage.tcl (manage_init): GDBTK -> "Foundry Debugger". + +Sun Nov 9 18:24:18 1997 Ian Lance Taylor <ian@cygnus.com> + + * memory.tcl (build_win): Use a single menu, remove ``Hide + menubar'' entry, add ^U binding. + * manage.tcl (manage_init): Change name of memory window from + ``Memory Dump'' to ``Memory''. + + * srcbar.tcl (create_buttons): Remove toggle update button. + + * src.tcl (update_title): Don't use colon if there is no file + name. + + * main.tcl: If GDBTK_IDE, initialize gdb_download_complete. + (gdbtk_tcl_preloop): If GDBTK_IDE, call download. + (ide_run_server): Don't run if we already have a run request. If + download is complete, run program as an idle callback. Otherwise, + wait until the download is complete before running the program. + (ide_do_run): New procedure to support ide_run_server. + (download): Don't run program. Set gdb_download_complete. + + * src.tcl (name): Give an error if the file does not exist. + (location): Only add files that exist to the file name combobox. + +Sun Nov 9 11:09:39 1997 Tom Tromey <tromey@cygnus.com> + + * src.tcl (name): Use better error message. + + * locals.tcl (build_win): New method. + * watch.tcl (build_win): Create menu. Watch -> "Add Watch". + (Menu): New instance variable. + (selectionChanged): New method. + (postMenu): "Stop Watching" -> Remove. + * variables.tcl (build_win): Set -ignoreinvoke on Tree widget, and + set -command to run editEntry method. Don't install <Double-1> + binding. Put headers on Tree widget. Run selectionChanged + method. + (editEntry): Renamed. Now takes entry name as argument. + (populate): Don't set -state disabled on new items. + (getSelection): New method. + (selectionChanged): New method. + (build_menu_helper): New method. + (postMenu): View->Format. + (build_win): Likewise. + + * variables.tcl (editXY): Only edit if entry is not empty. + + * srcbar.tcl (create_menu_items): Edit -> Open. + (create_buttons): Likewise. + +Thu Nov 6 11:00:41 1997 Tom Tromey <tromey@cygnus.com> + + * manage.tcl (manage_delete): Special-case deletion of pref window. + (manage_create): Don't special-case deletion of pref window. + +Thu Nov 6 13:57:32 1997 Ian Lance Taylor <ian@cygnus.com> + + * manage.tcl (manage_get_state): Return an empty string for a + withdrawn window and for the preferences window. + + * main.tcl (exe_name): Don't do anything if the executable name + has not actually changed. + +Wed Nov 5 23:08:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (download): Always specify exact filename + to load. + +Wed Nov 5 00:31:53 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_delete): Only delete source window if + user answers yes to query. + + * bp.tcl: Rewrite to include pulldown menu and new look. + + * register.tcl: Rewrite to include pulldown menu and new look. + + * stack.tcl: Open initial size wide enough to show all text. + + * src.tcl: Modified popup window. Remove option to open + multiple source windows because the IDE window code doesn't + work with it. + + * srcbar.tcl (_set_run): Change balloon message for Run. + + * variables.tcl, watch.tcl: Use fixed font. + + * toolbar.tcl (create_menu_items): Handle Close Debugger correctly. + + * mem_pref.tcl: Put focus and grab on window. + + * memory.tcl: Balloon message change. + +Mon Nov 3 11:04:44 1997 Tom Tromey <tromey@cygnus.com> + + * main.tcl (gdbtk_tcl_preloop): Look at main even if IDE running. + (ide_run_server): Open src window. + + * manage.tcl (manage_init): Don't recreate initial windows when + running under IDE. + +Fri Oct 31 00:00:04 1997 Tom Tromey <tromey@cygnus.com> + + * pref.tcl (cancel): Use manage delete. + * toolbar.tcl (create_menu_items): Don't register debugger + preference window. + * manage.tcl (manage_register_defaults): Use idewindow, not + idewindow_proc. + (manage_delete): Don't deregister preference window. + (manage): Added find, create_closed methods. + (manage_create): Added visibility argument; changed all callers. + Special case destruction of pref window. + * main.tcl: IDE window callback proc is "manage find". Register + debugger preference window. Create closed src and pref windows + initially. + (gdbtk_tcl_preloop): Don't create source window in IDE mode. + + * src.tcl (trace_variable): New method. + (constructor): Use variable traces to track target/exe changes. + (destructor): Remove variable traces. + +Thu Oct 30 12:50:28 1997 Martin M. Hunt <hunt@cygnus.com> + + * mem_pref.tcl: Change buttons to OK/Cancel/Apply. + Minor cleanup. + + * memory.tcl: New look. Added menubar. + +Tue Oct 28 23:03:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_buttons): Clean up balloon help + for buttons. + (create_menu_items): Move print menu items to srcbar.tcl. + Cleanup labels. + + * srcbar.tcl (create_menu_items): Add print menu items. + (create_buttons): Clean up balloon help for buttons. + +Tue Oct 28 17:26:15 1997 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_menu_items): Add print menu items. + (print): New function. Calls the proper print routine. + + * src.tcl (print): New function. Dump the contents + of the text widget to a printer. + +Tue Oct 28 01:06:15 1997 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_menu_items): Add new + preferences menu code. + + * pref.tcl (build_win): Remove all old ppreferences. + Add Connection and View preferences. + (cancel): New function. Restore previous values and + quit. + + * manage.tcl (manage_delete): Unregister preferences + on exit. + + * src.tcl (constructor): Add sizebox under Windows. + + * download.tcl (constructor): Remove shortcuts on buttons. + Put focus on "OK" button. + + * download_pref.tcl (cancel): New function. Restores + previous values. + +Tue Oct 21 15:28:29 1997 Tom Tromey <tromey@cygnus.com> + + * main.tcl: Main window now named "Foundry Debugger". + +Fri Oct 24 14:03:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_menu): Deleted. + (manage_delete): Notify IDE when windows are deleted. + (manage_raise): New function. + (manage_create): Notify IDE when a window is created. + + * download.tcl (constructor): Put focus on download + window. + + * toolbar.tcl (create_menu_items): Make "Window" menu + and IDE managed-menu, but don't put anything in it. + +Fri Oct 24 12:28:43 1997 Martin M. Hunt <hunt@cygnus.com> + + * toolbar.tcl (create_menu_items): Add View menu. + + * src.tcl (config_win): Add accelerators for new View + menu. + +Wed Oct 22 21:30:52 1997 Martin M. Hunt <hunt@cygnus.com> + + * download.tcl (Download): Make window local modal. + Raise it to top. + + * srcbar.tcl (create_buttons): Change border size on + address and line labels. Change balloon help. Remove + vertical line. + +Mon Oct 20 10:12:23 1997 Tom Tromey <tromey@cygnus.com> + + * toolbar.tcl (create_buttons): vmake window now named "Foundry + Project". + +Mon Oct 13 19:02:33 1997 Martin M. Hunt <hunt@cygnus.com> + + * bp.tcl (bp_modify): Change color of checkbuttons. + + * download.tcl (done): Write "DONE" on progress meters. + +Thu Oct 9 14:33:21 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl: Call ide_window_register restorer. + +Thu Oct 9 12:46:25 1997 Tom Tromey <tromey@cygnus.com> + + * src.tcl (updateBalloon): Changed name of balloon variable. + (showBalloon): Likewise. Use new "balloon show" command. + (SrcBalloon): Removed. + (TimeOut): Default is 1000 (1 second). + +Wed Oct 1 11:33:36 1997 Tom Tromey <tromey@cygnus.com> + + * main.tcl: Use "manage get_state" as window saver. + + * manage.tcl (manage): Added "restore", "get_state" options. + (manage_restore): New proc. + (manage_get_state): Likewise. + (manage_register_defaults): Use "manage get_state" as window + saver. + +Sun Sep 28 04:20:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * bp.tcl: Clean up the spacing to make the widget look better. + + * download_pref.tcl: Show the initial baud rate correctly. + + * download.tcl: Cleanup correctly when deleted. + + * main.tcl (gdb_tcl_preloop): Set baud rate. + (ide_run_server): Delay download 1 second. + (demo_it): Do gdb "next" commands every 2 seconds. + + * manage.tcl (manage_create): Withdraw window immediately then + deiconify it when done. + + * prefs.tcl (pref_set_defaults): Don't define stack bg color. + + * register.tcl: Withdraw window immediately so we don't have + to watch it slowly draw. Make it look more like memory window. + + * src.tcl: Fix major bug where source window got lost when + the source file was not found. Reconfigures more smoothly. + + * srcbar.tcl (create_menu_items): Comment out "Close Debugger" + menu item because it was broken. + + * stack.tcl: Use the same background color as the other windows. + + * toolbar.tcl: Add "Automatic Step" menu item. + +Fri Sep 26 21:10:11 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * download.tcl (done): display bytes loaded as an integer. + +Fri Sep 26 13:09:47 1997 Tom Tromey <tromey@cygnus.com> + + * images2/edit.gif: Replaced. + +Fri Sep 26 00:42:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (ide_run_server): Just call download. + (download): First set baud rate then target. Then, depending + on preferences set a breakpoint at 'main' and 'exit' and run. + (set_baud): New function. + + * download_pref.tcl (build_win) Add checkbuttons for "Run until + 'main'" and "Set breakpoint at 'exit'. + (change_baud): Set preference when baud changes. + + * pref.tcl (reconfig): Correct problem with download options. + + * prefs.tcl (pref_set_defaults): Define gdb/load/main, + gdb/load/exit, and gdb/load/baud. + + * src.tcl (location): Fix a problem where the browse tag was + sometimes not deleted. + + * manage.tcl: Add a window title for Download Options. + +Thu Sep 25 15:39:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * download_pref.tcl: New file. Creates a download options dialog. + + * manage.tcl: Add download prefs window to list. + + * toolbar.tcl: Add Download preferences to menu. + + * pref.tcl: Add Download to tab notebook preferences. + + * src.tcl: Set activebackground on popup to indicate color + of the breakpoint dot that will be set. + +Thu Sep 25 12:36:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * download.tcl (done): Make sure all indicators show download + completed, even if we weren't properly notified. + + * manage.tcl: Better support for windows that want to set + their own titles. + + * src.tcl (update_title): New function. Sets titlebar + to indicate current filename, and under IDE, executable and + target. + + * images2/reg.gif: Updated image. + +Thu Sep 25 08:58:44 1997 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (config_win): don't focus src window on Enter events + +Thu Sep 25 03:11:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl (ide_run_server): Set target and download automatically. + (download): Open a download window. + + * download.tcl: New file. Implements a download window. + + * manage.tcl (manage_init): Add download window. + (manage_create): If there is no title, don't try to set one and + don't try to set geometry. + + * registers.tcl: Make it look more like memory window. + + * toolbar.tcl, floatbar.tcl, srcbar.tcl: Update look of menus and toolbars + to be closer to prototype. + + * Makefile: Add download.tcl. + + * tclIndex: Rebuilt. + + * images/memory.gif: Update. + + * images/bp.gif: New file. Breakpoint icon. + +Wed Sep 24 07:43:47 1997 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl (VariableWin::build_win): add double-click binding to edit + (editXY): new method to support above + + * prefs.tcl (pref_set_defaults): add register window pref for highlight color + + * register.tcl (RegWin::constructor): set highlight and normal fg + (build_win): build window using grid geometry manager, not grid widget + (dimensions): new method + (fixLength): new method + (but3): use "Menu" (protected data) + (edit): use entry to edit values + (acceptEdit): new method + (unedit): new method + (update): change to use new grid layout and change highlighting + (reconfig): destroy scrolled window, too + ScrolledWin: new protected data + Menu: new protected data + Editing: new protected data + +Tue Sep 23 15:15:22 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl: If GDBTK_IDE, withdraw . before making any calls + across the IDE backplane. + * manage.tcl (manage_init): If using a floating toolbar, and + GDBTK_IDE, deiconify . to undo the withdrawal. + +Tue Sep 23 01:31:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl: Reorder calls to pref init and standard_look_and_feel. + + * global_pref.tcl: Change font requester to modify both src-font + and global.fixed. Change to be compatible with latest libide font code. + + * prefs.tcl: Changes to get working with latest libide font code. + +Mon Sep 22 15:16:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * memory.tcl: Add editing. Remove debugging lines. + Fix problems with resizing. + + * mem_pref.tcl: Remove debugging line. + +Fri Sep 19 08:22:25 1997 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl (build_win): use preferences + (getAllClassMembers): new method + (getPath): update to support C++ + + * watch.tcl (build_win): augment parent class' build_win instead of replacing it + + * stack.tcl (build_win): use preferences + (update): catch gdb_loc in case source window is not open yet + + * prefs.tcl (pref_set_defaults): add new defaults for all previously + hard-coded fonts and colors + + * global_pref.tcl (build_win): use preferences + + * console.tcl (Console::constructor): use preferences + + * bp.tcl (bp_add): use preferences + (bp_modify): use preferences + + + * src.tcl (SrcWin::constructor): use preferences + (build_win): use preferences + (config_win): use preferences, bind <Enter> to focus source window textbox + so that our keypresses always work + (SrcBalloon): new protected variable + (TimeOut): new common variable + +Wed Sep 17 13:54:29 1997 Tom Tromey <tromey@cygnus.com> + + * toolbar.tcl (build_win): Use standard_toolbar. + +Wed Sep 17 13:52:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (config_win): Set bg color back to default. + +Tue Sep 16 23:10:00 1997 Martin M. Hunt <hunt@cygnus.com> + + * images2/*: Delete unused icons. + +Tue Sep 16 21:30:40 1997 Martin M. Hunt <hunt@cygnus.com> + + * bp.tcl (bp_add): Add some padding to space things + out more. Anchor labels to the right side. + + * src.tcl: Fix problem where breakpoints were disappearing + when files changed. + +Tue Sep 16 17:45:05 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl: Change manage_create and manage_open to accept + a variable number of args. Add mem and mempref window types. + Fix pref save call. + + * memory.tcl: New file. Implements a memory dump window. + Currently read-only. + + * mem_pref.tcl: New file. Implements options dialog for + memory dump window. + + * pref.tcl, toolbar_pref.tcl, register.tcl, src_pref.tcl, + global_pref.tcl, about.tcl: Make "attach" a public config + variable. + + * main.tcl: Use standard_look_and_feel. + + * Makefile, tclIndex: Rebuilt. + + * images/check.gif: A check mark image. + + * images/stop.gif: Fix transparency. + +Tue Sep 16 08:13:03 1997 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl (getVariable): fix off by one error when a breakpoint + is set at a line + (hasBreakpoint): new method + (SrcWin): add idle hook for source balloons + (updateBalloon): new method + (showBalloon): use register_balloon + (register_balloon): new method + +Tue Sep 16 05:55:31 1997 Keith Seitz <keiths@onions.cygnus.com> + + * watch.tcl (add): use a little more robust (if more obscure) method + of determining validity of a variable name + (label): translate % to $ in names + + * variables.tcl (Variable::setType): allow for convenience variables + (Variable::isConvenience): new method + (Variable::displayHex): allow for convenience variables + (VariableWin::edit): do not eval $data when editing (for conv. vars) + (VariableWin::postMenu): use virtual method label to title popup + +Fri Sep 12 12:17:13 1997 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl (Variable::value): when no display style specified, + choose some reasonable default for the given type + + * src.tcl (config_win): ad bindings to support variable balloons in source mode + (getVariable): new method + (cancelMotion): new method + (motion): new method + (showBalloon): new method + timeoutID: new protected variable + TimeOut: new protected variable + +Fri Sep 12 05:47:56 1997 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl (getLocals): return empty list when no locals present. + +Thu Sep 11 14:13:19 1997 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl (VariableWin::build_win): change popup construction + (VariableWin::postMenu): redo menu layout to use dynamic idices of + panes + (VariableWin::edit): new method + (VariableWin::UnEdit): new method + (VariableWin::changeValue): new method + (VariableWin::getPath): handle unamed unions/structs and arrays more + intelligently + VariableWin::Editing: new protected variable + VariableWin::EditEntry: new protected variable + (Variable::isOpenable): make sure we can open unions + (Variable::isUnamed): new method + (Variable::isUnion): new method + (Variable::setType): handle unions and unamed structs/unions better + (Variable::displayHex): unions, structs only display in hex + (Variable::isArray): new method + (Variable::isEnum): new method + (Variable::isEditable): new method + (Variable::value): enums now show symbol values, too. Analogous to char + and char*. + + * watch.tcl (WatchWin::build_win): change popup construction + (WatchWin::postMenu): redo menu layout to use dynamic indices of panes + + +Wed Sep 10 20:44:12 1997 Ian Lance Taylor <ian@cygnus.com> + + * manage.tcl (manage_register_defaults): Rename from + manage_register_default. Take a list of windows. + (manage_menu): Invoke manage_register_defaults once as an idle + callback, rather than invoking manage_register_default in many + different idle callbacks. + +Wed Sep 10 00:49:23 1997 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (edit): Don't start editor if we're not + debugging anything. + + * main.tcl: Keep correct colorscheme for windows. + +Mon Sep 8 12:10:26 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_restart): Only restart toolbar once. + + * global_pref.tcl: Minor fix. + + * images2/vmake.gif: Fix transparency. + +Mon Sep 8 13:05:11 1997 Ian Lance Taylor <ian@cygnus.com> + + * interface.tcl (gdbtk_tcl_query): Use tk_messageBox rather than + tk_dialog. + + * main.tcl: Register check and exit handlers using new commands + provided by gdbtk. + +Mon Sep 8 03:01:25 1997 Martin M. Hunt <hunt@cygnus.com> + + * global_pref.tcl (build_win): Some font fixes. + +Mon Sep 8 02:25:17 1997 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl: Make disabled breakpoints black. + Make comboboxes only use scrollbars when needed. + + * interface.tcl (gdbtk_tcl_breakpoint): Change to support + changes in gdbtk.c. Supply breakpoint number to hooks. + + * manage.tcl: Add breakpoint window. Add support for + dynamically attaching/detaching toolbars. + + * bp.tcl: New file. Breakpoint window. + + * main.tcl: Change palette for debugging. + + * pref.tcl: New file. Preferences dialog. + + * floatbar.tcl: Add target and download buttons. + Add spacing. + + * srcbar.tcl, toolbar.tcl: Change to use flat icons. Work with + floating toolbar if requested. + + * prefs.tcl: Define new preferences to force toolbar + to float or be attached to the source windows. + + * global_pref.tcl: Remove icon requester. + + * toolbar_pref.tcl: Add icon combobox. Add checkbuttons + for forcing toolbar to either float or be attached to src window. + + * Makefile: Add bp.tcl + + * images/*: Fix transparency and add new icons. + + * images2/*: Add flat icons. + +Fri Sep 5 20:24:07 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl: Register an exit handler when using the IDE. + +Thu Sep 4 11:47:38 1997 Martin M. Hunt <hunt@cygnus.com> + + * ALL: Change preferences to use new preferences. + Change "dbug" calls to "debug". + + * pref.tcl: New file. Local preferences read/write. + + * gettext.tcl, debug.tcl, balloon.tcl: Delete. Use + versions from libide instead. + +Wed Sep 3 09:20:13 1997 Tom Tromey <tromey@cygnus.com> + + * main.tcl (add): Pass idewindow_no_state to idewindow_proc. + * manage.tcl (manage_register_default): Pass idewindow_no_state to + idewindow_proc. + +Mon Aug 25 05:59:01 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * images2/{finished.gif, finishedu.gif, nextd.gif nextu.gif, + stepd.gif, stepu.gif}: Use icons with straight brackets + instead of slanted. + + * prefs.tcl (pref_set_defaults): Set default debugMode to 0. + + * register.tcl (build_win): Change font to fixed and bg to white. + + * src.tcl: Change all references to fonts to "src-font". + + * global_pref.tcl: Change font requester to do src-font. + + * srcbar.tcl: Change address and line labels to use + src-font and be sunken. + + * stack.tcl: Chnage bg to white and fonr to src-font. + +Mon Aug 25 03:06:35 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * src.tcl: (set_status) check if inferior is running first, and reset + message for status window if it is not. + + +Mon Aug 25 00:28:39 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * srcbar.tcl: Change stack images to be consistent with others. + + * images2/{upu.gif,upd.gif,bottomd.gif,bottomu.gif,downu.gif, + downd.gif}: New stack images. + + * images2/edit[ud].gif: Correct quantization and transparency. + + * manage.tcl (manage_delete): Kill gdb when all source windows + are deleted. + (manage_create): Only add IDE entries on the first source window. + + * src.tcl (do_popup): Don't map window if already mapped. Fixes + problem with tk_popup. Change menu items. + +Mon Aug 25 00:24:43 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * src.tcl: (set_status) change to using gdb_target_has_execution to + determine if the target is running + +Sun Aug 24 23:02:19 1997 Tom Tromey <tromey@cygnus.com> + + * toolbar.tcl (build_win): Make sure object is deleted when window + is destroyed. + (destructor): Don't destroy containing widget; just us. + + * srcbar.tcl (create_menu_items): Added Exit item to menu. + + * src.tcl (build_win): Use grid, not packer, to lay out main + window. + (mode): Pack new text widget into pane; don't repack the pane + itself. + +Sun Aug 24 22:06:30 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * varialbes.tcl: (build_win) set hlist font to 'tix option get + fixed_font', change selectBackground to Hlist background, select- + BorderWidth to 0, selectForeground to black. Use tk_popup instead of + tixPopup widget. + (postMenu) make necessary tk_popup changes, make sure functions are + only allowed to be displayed in hex. + (isFunction) new method + (displayHex) functions only displayable as hex + (value) extract the address of functions for value + * watch.tcl: (constructor) remove popup menu customization + (build_win) change from tixPopup to tk_popup, hack the + hlist options to use the correct font, etc as in variables.tcl, + (validateEntry) always erase the contents of the entry + (postMenu) make all changes to use tk_popup and move the "Stop + watching" menu addition here + (label) make sure that we use "foo.bar" and "foo->bar" correctly + (add) fix typo preventing recognition of variables already being + watched + +Sun Aug 24 18:49:16 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * console.tcl (invoke): Don't display error messages in console window. + (constructor): Enable cut-and-paste. Fix intermittant bug. + + * main.tcl (gdbtk_tcl_preloop): Don't automatically do anything + but issue the file command. + (download): Issue load command. Called when icon is selected. + (set_target): Issue target command. Called when target + icon is selected. + + * srcbar.tcl: Add target and download buttons to toolbar. + +Sun Aug 24 20:30:41 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl (gdbtk_tcl_preloop): If GDBTK_IDE, then automatically + set file and target based on properties. If using the simulator, + load the executable. Catch and ignore errors from setting the + source window to show main. + +Sun Aug 24 14:39:23 1997 Tom Tromey <tromey@cygnus.com> + + * src.tcl (constructor): Don't set `editor'. + (location): Never update external editor. + (edit): Don't set `editor'. + (editor): Removed instance variable. + + * images2/stepiu.gif, images2/stepid.gif, images2/nextiu.gif, + images2/nextid.gif: Installed new versions. + + * srcbar.tcl (_toggle_updates): Pass $updatevalue to + updatecommand. + (destructor): Implemented. + (_set_stepi): New method. + (displaymode): Run _set_stepi when changed. + (updatevalue): Global state stored in global array. + (create_buttons): Create stepi, nexti buttons. Run _set_stepi. + (_load_src_images): Create stepi, nexti icons. + + * images2/stepiu.gif, images2/stepid.gif, images2/nextiu.gif, + images2/nextid.gif: New images. + (create_buttons): Likewise. + + * src.tcl (toggle_updates): Use $value, not $a. + + * src.tcl (mode): Don't change commands on (nonexistent) step/next + buttons. + + * toolbar.tcl (create_buttons): Added watch button. + (_load_images): Create watch images. + * images2/watchd.gif, images2/watchu.gif: New files. + * images2/varsd.gif, images2/varsu.gif: Changed. + + * images2/*: Removed old images, added many new images. + + * prefs.tcl (pref_set_defaults): Default images are in images2 + directory. + * src.tcl (build_win): Make a GDBSrcBar. + (location): address and line information now in toolbar. + (mode): Set -displaymode on toolbar. + (update): Set -running on toolbar. + (busy): Likewise. + (edit): Now a method, not a proc. + (toggle_updates): Added "value" argument. + * Makefile (TCL): Added srcbar.tcl, floatbar.tcl. + * toolbar.tcl (create_buttons): New method. + (create_menu_items): Likewise. + (build_win): Run create_menu_items and create_buttons. Move most + of body into these methods. Removed Exit command from File menu. + (_loaded_images): New common variable. + (_load_images): New method. + (create_buttons): Run it. + (create_menu_items): Removed Tools menu. + (configure): Renamed from config. + * srcbar.tcl: New file. Implements toolbar attached to source + window. + * floatbar.tcl: New file. Implements floating toolbar. + * manage.tcl (manage_init): toolbar-type is GDBFloatBar. + (manage_init): Don't create toolbar if running under IDE. + +Sun Aug 24 13:05:22 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * manage.tcl (manage_init): Remove idemenuname from + the _manage_objects array; it was redundant. + (manage_create): Stop notifying IDE about new transient + windows. + +Sun Aug 24 01:07:29 1997 Tom Tromey <tromey@cygnus.com> + + * about.tcl, console.tcl, global_pref.tcl, prefs.tcl, + register.tcl, src.tcl, src_pref.tcl, stack.tcl, toolbar.tcl, + toolbar_pref.tcl: Added Copyright statement. + + * Makefile (tags, TAGS): New targets. + + * toolbar.tcl (build_win): Quit->Exit. Only display this item if + not using the IDE. + +Sat Aug 23 21:55:54 1997 Ian Lance Taylor <ian@cygnus.com> + + * src.tcl (SrcWin update): Set command for stop icon. + (SrcWin busy): Likewise. + + * manage.tcl: Move comments out of array initialization. + +Sat Aug 23 17:36:06 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * src.tcl (name): Handle case where files are part of the + sources, but are unreadable. + (build_win): Set filename combobox size to default. + + * manage.tcl: Remove breakpoint window from window list. + +Sat Aug 23 16:49:53 1997 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl: remove old breakdot stuff + (reconfig) make sure we redraw the breakdots when font changes + (file) check for duplicate break-able lines + * variables.tcl: remove debug output + * watch.tcl: add entry field to enter watch expressions + +Sat Aug 23 17:44:45 1997 Ian Lance Taylor <ian@cygnus.com> + + * manage.tcl (manage_create): Register the window if it is not + already registered, rather than if it is already registered. + + * src.tcl (SrcWin config_win): Add special double and triple click + bindings to override standard text bindings in break dot area. + + * prefs.tcl (pref_set_defaults): Set the global font to the Tix + default font. Set the src font to the Tix default fixed font. + * src.tcl (SrcWin config_win): Configure the text font. + * console.tcl (Console constructor): Set the cont to the Tix + fixed font. + +Fri Aug 22 20:42:51 1997 Keith Seitz <keiths@onions.cygnus.com> + + * src.tcl: add breakpoint image that is text-size insensitive + change layout of source, assembly, and mixed windows to use + tabs, if possible, allowing more clickable area for toggling + breakpoints, etc. + * variables.tcl: (VariableWin::isFloat) new method + (VariableWin::value) make sure floats are output as floats + when user specifies "decimal" output + +Fri Aug 22 16:23:32 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * src.tcl (goto_func): Catch errors. + +Fri Aug 22 16:35:39 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl: Use underscores rather than dashes in variable names. + (ide_run_server): Make gdb_target_name global. Call file before + calling target. Call load before calling run. + +Fri Aug 22 12:15:06 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * debug.tcl (dbug): Make debug window scrolled. Make it + work with standalone gdb. + + * prefs.tcl (pref_save): Fix puts that were incorrectly + changed to dbug. + +Thu Aug 21 17:57:59 1997 Martin M. Hunt <hunt@cygnus.com> + + * ALL: Change all "puts" to "dbug". + + * debug.tcl: New file. Opens a window for debugging messages. + +Thu Aug 21 14:30:53 1997 Keith Seitz <keiths@onions.cygnus.com> + + * watch.tcl: (add) strip commas, too + +Thu Aug 21 14:26:36 1997 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl: (buid_win) use listbox's font for font measuring + +Thu Aug 21 02:52:35 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * src.tcl (name): Check source filenames and handle errors + if not found. + + * variables.tcl (destructor): Display styles are not + objects so must be destroyed instead of deleted. + (name): comment out debugging line. + + * main.tcl: Add stuff from standard_look_and_feel. + + * prefs.tcl, manage.tcl: Minor cleanup. + +Thu Aug 21 00:39:35 1997 Martin M. Hunt <hunt@pern.cygnus.com> + + * main.tcl (ide_run_server) New function. Starts GDB when + asked politely. + (target_name): New function. Watches for changes in the target + name. + (exe_name): New function. Watches for changes in the + executable name. + + * console.tcl (insert, einsert): Scroll so the insertion + point can be seen. + + * manage.tcl: SPecial hacks to create a global "console". + Needed because we can't have puts searching for a console + window everytime a puts arrives. + + * interface.tcl (gdbtk_tcl_fputs, gdbtk_tcl_fputs_error): + Write to the console if one exists, and do an update. + + * tclIndex: Rebuilt. + +Wed Aug 20 17:23:07 1997 Keith Seitz <keiths@onions.cygnus.com> + + * variables.tcl: (Variable::setType VariableWin::getPath) handle types + with multiple names (unsigned char, long long unsigned int) properly + * locals.tcl: (update) comment out debug info + +Wed Aug 20 16:36:49 1997 Keith Seitz <keiths@pizza.cygnus.com> + + * watch.tcl: (add) try to handle errors more gracefully + * variables.tcl: (value) make sure we handle bad pointer + dereferences nicely + (lots of places) switch to using 'ouput' instead of 'print' + +Wed Aug 20 11:43:35 1997 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (file): Handle case where source files do + not have any lines which generate code. + (set_status): Keep status to one line. + +Wed Aug 20 00:00:52 1997 Tom Tromey <tromey@sanguine.cygnus.com> + + * images2/build.gif, images2/file.gif, images2/reg.gif, + images2/stop.gif, images2/continue.gif, images2/finish.gif, + images2/next.gif, images2/step.gif, images2/run.gif: New files. + +Tue Aug 19 14:52:59 1997 Keith Seitz <keiths@onions.cygnus.com> + + * tclIndex: rebuilt + * Makefile: add variables.tcl, watch.tcl, and locals.tcl + * manage.tcl: (manage_init): add locals window + * src.tcl: (do_popup): add binding for watch window + (addToWatch): new method + * locals.tcl: new file + * variables.tcl: new file + * watch.tcl: new file + + +Mon Aug 18 01:28:19 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl: Change window names to have only first + char of each word capitalized. + + * global_pref.tcl (get_file): Handle bad pathnames. + +Sun Aug 17 01:59:02 1997 Martin M. Hunt <hunt@cygnus.com> + + * register.tcl (destructor): Call manage delete. + * global_pref.tcl (destructor): Call manage delete. + * prefs.tcl (destructor): Call manage delete. + * src_pref.tcl (destructor): Call manage delete. + * toolbar_pref.tcl (destructor): Call manage delete. + + * manage.tcl: (manage_delete): Remove windows that + have been quit, rather than killed by window manager. + + * src.tcl (location): Don't call gdb_listfuncs on + NULL filenames. + +Sun Aug 17 00:18:02 1997 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl: Major changes to support file browsing. + Also bug fixes for assembly mode, new comboboxes + for filename and function selection. + + * src_pref.tcl: New file. Allows selection of + colors used in source display. + + * prefs.tcl: Add new window type for src prefs. + Set default colors for source window. + + * manage.tcl (manage_init): Add srcpref window type. + (manage_restart): Preserve window geometries on restarts. + + * Makefile: Add src_pref.tcl. + + * tclIndex: Rebuilt. + + * toolbar.tcl: Add call to source prefs. + + * main.tcl: Change initial "src file" call to + "src location". + +Thu Aug 14 15:49:02 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_create): Some fixes for IDE windows. + +Thu Aug 14 03:18:10 1997 Martin M. Hunt <hunt@cygnus.com> + + * register.tcl, stack.tcl (destructor): Remove hook. + + * manage.tcl: Mostly rewritten from scratch to be + more efficient and handle multiple windows of the same type. + (manage_open): New function opens or creates a window + as necessary. + (manage_create): Now always creates a new window. + + * global_pref.tcl (build_win): Only put up font message + box on Unix systems. + + * main.tcl: Change "manage create" calls to "manage open" + + * src (destructor): Remove hooks. + (do_popup): Add a menu item to open another source window. + + * toolbar.tcl (build_win): Change "manage create" calls to + "manage open". Bind button 3 on iconbar to "manage create". + + * prefs.tcl: Changes required for new features in manage.tcl. + + * tclIndex: Rebuilt. + + * hooks.tcl (remove_hook): Fix. + (lremove): New function. + +Tue Aug 12 16:06:04 1997 Ian Lance Taylor <ian@cygnus.com> + + * main.tcl: If running in the IDE, register the source window as + the generic gdb window. + +Tue Aug 12 01:42:10 1997 Martin M. Hunt <hunt@cygnus.com> + + * global_pref.tcl (build_win): Add a font size control + widget, and a font preview window. Implement scanning + for fixed-width fonts and a font cache. + (font_changed): Save all font attributes in new-style + font description. + + * balloon.tcl: Merge in latest changes from libide. + + * prefs.tcl (pref): Rename variables to make function + clearer. + (pref_init): After reading in prefs file, create + all named fonts. + (pref_set_defaults): Set default font to {courier 12 roman}. + +Mon Aug 11 13:47:49 1997 Martin M. Hunt <hunt@cygnus.com> + + * tclIndex: New file. + + * Makefile: New file. Generates tclIndex when needed. + + * manage.tcl (manage_init): Add an icon for GDB. + (manage_create): Bind Map and Unmap for toolbar toplevel. + Tell window manager to display icon if one exists. + (manage_iconify): Iconify or deiconify all windows. + (make_icon_window): Build a window with an icon in it. + (bind_for_toplevel_only): Local copy, because if you build + GDB without IDE you won't get the one in libide. + + * main.tcl: Remove all the source commands. + + * toolbar.tcl: Use "-menu" configuration option for toplevel. + + * images/cygnus_icon.gif: A cygnus logo with GDB on it. + For Unix window managers. + +Fri Aug 8 16:01:20 1997 Ian Lance Taylor <ian@cygnus.com> + + * manage.tcl (manage): Add menu subcommand. + (manage_init): Add -menu, -menuname, and -idemenuname options for + all the windows. + (manage_create): Register transient windows. + (manage_menu, manage_register_default): New procedures. + * toolbar.tcl (build_win): Call manage_menu to set up the window + menu. + +Thu Aug 7 16:51:43 1997 Martin M. Hunt <hunt@cygnus.com> + + * stack.tcl: Bind button 1 to select current + frame. Add balloonhelp. + +Thu Aug 7 14:00:18 1997 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl, manage.tcl, toolbar.tcl: Add support + for stack window. + + * stack.tcl, images/stack.gif: New files. + + * ALL: Change "::" to "@@" for itcl1.5/tcl8.0. You + muct now use tcl8 for gdbtk to work. + +Tue Aug 5 12:10:43 1997 Martin M. Hunt <hunt@cygnus.com> + + * register.tcl, global_pref.tcl: Change color "darkred" + to red so it will work on windows. + +Tue Aug 5 12:01:26 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_init): Unset prefs are now "" + instead of 0. + +Tue Aug 5 02:21:47 1997 Martin M. Hunt <hunt@cygnus.com> + + * images*/run.gif: Change to green again. + +Tue Aug 5 01:42:56 1997 Martin M. Hunt <hunt@cygnus.com> + + * main.tcl: Source register.tcl + + * register.tcl: New file. Editable register window + and register preferences. + + * toolbar.tcl: Add hooks for register prefs. + + * manage.tcl: Add register window to list of windows. + Deiconify windows when requested. + + * src.tcl: Minor changes. + + * global_pref.tcl: Bind return key to image dir entry + widget. + + * prefs.tcl: Add register prefs to notebook widget. + Change default for pref get to {} instead of 0. + +Fri Aug 1 14:21:25 1997 Martin M. Hunt <hunt@cygnus.com> + + * images/*: Smaller toolbar icons. Fix some gifs + to be transparent. + +Thu Jul 31 01:20:51 1997 Martin M. Hunt <hunt@cygnus.com> + + * src.tcl (mode): Don't try to display EDIT button + in any mode. + +Thu Jul 31 00:56:26 1997 Martin M. Hunt <hunt@cygnus.com> + + * global_pref.tcl (build_win): Add ComboBox for simple font selection. + + * prefs.tcl (pref_init): Allow "option" commands in init file. + + * src.tcl: Remove EDIT button. Change fonts to use global font if + no src font is specified. + + * toolbar.tcl: Enable Tools/Edit pulldown menu. + +Wed Jul 30 14:43:49 1997 Martin M. Hunt <hunt@cygnus.com> + + * about.tcl (build_win): Set bg to white for Cygnus gif. + +Wed Jul 30 14:39:49 1997 Martin M. Hunt <hunt@cygnus.com> + + * manage.tcl (manage_create): Fix window raising. + +Wed Jul 30 13:40:11 1997 Martin M. Hunt <hunt@cygnus.com> + + * initial checkin. + diff --git a/gdb/gdbtk/library/Makefile b/gdb/gdbtk/library/Makefile new file mode 100644 index 00000000000..53953ad9e0c --- /dev/null +++ b/gdb/gdbtk/library/Makefile @@ -0,0 +1,11 @@ + +TCL := $(wildcard *.tcl *.ith *.itb) + +ITCL_SH = itclsh3.0 + +tclIndex: $(TCL) Makefile + echo "auto_mkindex `pwd` $(TCL)" | $(ITCL_SH) + +tags: TAGS +TAGS: $(TCL) + etags --lang=none --regex='/[ \t]*\(proc\|method\|itcl_class\)[ \t]+\([^ \t]+\)/\1/' $(TCL) diff --git a/gdb/gdbtk/library/about.tcl b/gdb/gdbtk/library/about.tcl new file mode 100644 index 00000000000..292eecd7318 --- /dev/null +++ b/gdb/gdbtk/library/about.tcl @@ -0,0 +1,42 @@ +# About window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements About window +# ---------------------------------------------------------------------- + +class About { + inherit ManagedWin ModalDialog + constructor {args} { + global gdb_ImageDir + set f [frame $itk_interior.f] + label $f.image1 -bg white -image \ + [image create photo -file [file join $gdb_ImageDir insight.gif]] + message $f.m -bg white -fg black -text [gdb_cmd {show version}] -aspect 500 -relief flat + pack $f.image1 $f.m $itk_interior.f -fill both -expand yes + pack $itk_interior + bind $f.image1 <1> [code $this unpost] + bind $f.m <1> [code $this unpost] + window_name "About Cygnus Insight" + } + + # Don't quit if this is the last window. The only way that this can + # happen is if we are the splash screen. + + method quit_if_last {} { + return 0 + } + +} + diff --git a/gdb/gdbtk/library/actiondlg.tcl b/gdb/gdbtk/library/actiondlg.tcl new file mode 100644 index 00000000000..c446b7ed4fd --- /dev/null +++ b/gdb/gdbtk/library/actiondlg.tcl @@ -0,0 +1,818 @@ +# Tracepoint actions dialog for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +itcl_class ActionDlg { + # ------------------------------------------------------------------ + # CONSTRUCTOR + # ------------------------------------------------------------------ + constructor {config} { + global _TStepCount _TOtherVariable + + set class [$this info class] + set hull [namespace tail $this] + set old_name $this + ::rename $this $this-tmp- + ::frame $hull -class $class + ::rename $hull $old_name-win- + ::rename $this $old_name + + set top [winfo toplevel [namespace tail $this]] + wm withdraw $top + + set Registers [gdb_regnames] + if {$Line != ""} { + set Locals [gdb_get_locals "$File:$Line"] + set Args [gdb_get_args "$File:$Line"] + } else { + set Locals [gdb_get_locals "*$Address"] + set Args [gdb_get_args "*$Address"] + } + set Variables [concat $Locals $Args] + foreach a $Registers { + lappend Variables "\$$a" + } + + if {[llength $Args] > 0} { + lappend Variables "All Arguments" + } + if {[llength $Locals] > 0} { + lappend Variables "All Locals" + } + lappend Variables "All Registers" + lappend Variables "Collect Stack" + + build_win $this + + # Set a default return status, in case we are destroyed + set _TOtherVariable {} + + # Fill the listboxes with any default data + if {"$Data" != {}} { + change 1 $Data + } + + after idle [list wm deiconify $top] + # after idle grab $this + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - destroy window containing widget + # ------------------------------------------------------------------ + destructor { + + # Remove this window and all hooks + # grab release $this + + # Note that this is okay: the callback (TraceDlg::done, usually) will + # ignore stray "cancel" callbacks + eval $Callback cancel + + set top [winfo toplevel [namespace tail $this]] + destroy $this + destroy $top + } + + # ------------------------------------------------------------------ + # METHOD: build_win - build the Trace dialog box (cache this?) + # ------------------------------------------------------------------ + method build_win {f} { + global _TStepCount _TOtherVariable + + # The two frames of this dialog + set bbox [frame $f.bbox]; # for holding OK,CANCEL buttons + set data [frame $f.data]; # for everything else + + # Setup the button box + button $bbox.ok -text OK -command "$this ok" + button $bbox.cancel -text CANCEL -command "$this cancel" + pack $bbox.ok $bbox.cancel -side left -padx 10 -expand yes + + # The "Data Collection" Frame + set top [frame $data.top] + set bot [frame $data.bot] + + set boxes [frame $top.boxes] + set cFrame [frame $boxes.cFrame] + set vFrame [frame $boxes.vFrame] + set bFrame [frame $boxes.bframe] + set oFrame [frame $top.uFrame] + pack $cFrame $bFrame $vFrame -side left -expand yes -padx 5 + + # While stepping + if {$WhileStepping} { + set step_frame [frame $top.stepf] + label $step_frame.whilelbl -text {While Stepping, Steps:} + set WhileSteppingEntry [entry $step_frame.steps \ + -textvariable _TStepCount \ + -width 5] + pack $step_frame.whilelbl $WhileSteppingEntry -side left + } + + # The Collect listbox + label $cFrame.lbl -text {Collect:} + tixScrolledListBox $cFrame.lb -scrollbar auto \ + -browsecmd "$this toggle_button_state 0" \ + -command "$this change 0" + set CollectLB [$cFrame.lb subwidget listbox] + $CollectLB configure -selectmode extended + pack $cFrame.lbl $cFrame.lb -side top -expand yes -pady 2 + + # The Variables listbox + label $vFrame.lbl -text {Variables:} + tixScrolledListBox $vFrame.lb -scrollbar auto \ + -browsecmd "$this toggle_button_state 1" \ + -command "$this change 1" + set VariablesLB [$vFrame.lb subwidget listbox] + $VariablesLB configure -selectmode extended + pack $vFrame.lbl $vFrame.lb -side top -expand yes -pady 2 + + # The button frame + set AddButton [button $bFrame.add -text {<<< Collect} \ + -command "$this change 1" -state disabled] + set RemoveButton [button $bFrame.del -text {Ignore >>>} \ + -command "$this change 0" -state disabled] + pack $bFrame.add $bFrame.del -side top -expand yes -pady 5 + + # The other frame (type-in) + label $oFrame.lbl -text {Other:} + set OtherEntry [entry $oFrame.ent -textvariable _TOtherVariable] + pack $oFrame.lbl $OtherEntry -side left + bind $OtherEntry <Return> "$this change_other" + + # Pack these frames + if {$WhileStepping} { + pack $step_frame -side top + } + + pack $boxes $oFrame -side top -padx 5 -pady 5 + pack $top $bot -side top + + # Fill the list boxes + fill_listboxes + + # Pack the main frames + # after idle + pack $f.data $bbox -side top -padx 4 -pady 2 \ + -expand yes -fill x + + # !!??? + if {$WhileStepping} { + $WhileSteppingEntry delete 0 end + $WhileSteppingEntry insert 0 $Steps + } + } + + method toggle_button_state {add} { + + # BUG in Tix.. This is invoked whenever a <1> event is generated in + # the listbox... + if {$add} { + set a [$VariablesLB curselection] + if {"$a" != ""} { + $AddButton configure -state normal + $RemoveButton configure -state disabled + } + } else { + set a [$CollectLB curselection] + if {"$a" != ""} { + $AddButton configure -state disabled + $RemoveButton configure -state normal + } + } + } + + + # ------------------------------------------------------------------ + # METHOD: fill_listboxes - fills the two listboxes + # ------------------------------------------------------------------ + method fill_listboxes {{last {}}} { + + # Fill the Collect listbox with the variables being collected + if {[info exists Collect]} { + fill_collect $last + } + + fill_variables $last + } + + # ------------------------------------------------------------------ + # METHOD: change - change a selected variable + # ------------------------------------------------------------------ + method change {add {select {}}} { + if {"$select" == {}} { + set selections [get_selections $add] + set lb [lindex $selections 0] + set last [lindex $selections 1] + set selection [lindex $selections 2] + set noname 1 + } else { + # This usually (only) occurs when we open this dialog for editing + # some existing action. + set lb {} + set last {} + set noname 0 + set selection $select + } + + $RemoveButton configure -state disabled + $AddButton configure -state disabled + + # Remove all the selections from one list + # and add them to the other list + if {$add} { + set list1 $Variables + set list2 $Collect + } else { + set list1 $Collect + set list2 $Variables + } + + foreach a $selection { + if {$noname} { + set name [$lb get $a] + } else { + set name $a + } + + if {"$name" == "All Locals" || "$name" == {$loc}} { + set name "All Locals" + set lists [all_locals $add] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } elseif {"$name" == "All Registers" || "$name" == {$reg}} { + set name "All Registers" + set lists [all_regs $add] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } elseif {"$name" == "All Arguments" || "$name" == {$arg}} { + set name "All Arguments" + set lists [all_args $add] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } else { + set i [lsearch -exact $list1 $name] + set list1 [lreplace $list1 $i $i] + + # Check if this is something we want to keep on a list + if {[lsearch $Args $name] != -1 || [lsearch $Registers [string trim $name \$]] != -1 || [lsearch $Locals $name] != -1 || $add} { + lappend list2 $name + } + } + + if {$add} { + set Collect $list2 + set Variables $list1 + } else { + set Collect $list1 + set Variables $list2 + } + } + + # Update boxes (!! SLOW !!) + fill_collect $last + fill_variables $last + } + + # ------------------------------------------------------------------ + # METHOD: fill_collect - fill the collect box + # ------------------------------------------------------------------ + method fill_collect {{last {}}} { + + $CollectLB delete 0 end + set Collect [sort $Collect] + foreach a $Collect { + $CollectLB insert end $a + } + if {"$last" != ""} { + $CollectLB see $last + } + } + + # ------------------------------------------------------------------ + # METHOD: fill_variables - fill the variables box + # ------------------------------------------------------------------ + method fill_variables {{last {}}} { + + $VariablesLB delete 0 end + set Variables [sort $Variables] + foreach a $Variables { + $VariablesLB insert end $a + } + + if {"$last" != ""} { + $VariablesLB see $last + } + } + + # ------------------------------------------------------------------ + # METHOD: sort - sort a list of variables, placing regs and + # special identifiers (like "All Locals") at end + # ------------------------------------------------------------------ + method sort {list} { + + set special_names { + "All Arguments" args \ + "All Locals" locs \ + "All Registers" regs \ + "Collect Stack" stack + } + + foreach {name var} $special_names { + set i [lsearch $list $name] + if {$i != -1} { + set $var 1 + set list [lreplace $list $i $i] + } else { + set $var 0 + } + } + + # Extract all the locals, regs, args, globals + set types_list {Args Locals Registers } + foreach type $types_list { + set used_$type {} + + foreach a [set $type] { + set i [lsearch $list $a] + if {$i != -1} { + lappend used_$type $a + set list [lreplace $list $i $i] + } + } + set used_$type [lsort [set used_$type]] + } + + set globals [lsort $list] + + # Sort the remaining list in order: args, locals, globals, regs + set list [concat $used_Args $used_Locals $globals $used_Registers] + + set list2 {} + + foreach {name var} $special_names { + if {[set $var]} { + lappend list2 $name + } + } + + set list [concat $list2 $list] + return $list + } + + # ------------------------------------------------------------------ + # METHOD: all_args - add/remove all args + # ------------------------------------------------------------------ + method all_args {add} { + + if {$add} { + set list1 $Variables + set list2 $Collect + } else { + set list1 $Collect + set list2 $Variables + } + +# foreach var $Args { +# set i [lsearch $list1 $var] +# if {$i != -1} { +# set list1 [lreplace $list1 $i $i] +# lappend list2 $var +# } +# } + + lappend list2 "All Arguments" + set i [lsearch $list1 "All Arguments"] + if {$i != -1} { + set list1 [lreplace $list1 $i $i] + } + + return [list $list1 $list2] + } + + # ------------------------------------------------------------------ + # METHOD: all_locals - add/remove all locals + # ------------------------------------------------------------------ + method all_locals {add} { + + if {$add} { + set list1 $Variables + set list2 $Collect + } else { + set list1 $Collect + set list2 $Variables + } + +# foreach var $Locals { +# set i [lsearch $list1 $var] +# if {$i != -1} { +# set list1 [lreplace $list1 $i $i] +# lappend list2 $var +# } +# } + + lappend list2 "All Locals" + set i [lsearch $list1 "All Locals"] + if {$i != -1} { + set list1 [lreplace $list1 $i $i] + } + + return [list $list1 $list2] + } + + # ------------------------------------------------------------------ + # METHOD: all_regs - add/remove all registers + # ------------------------------------------------------------------ + method all_regs {add} { + + if {$add} { + set list1 $Variables + set list2 $Collect + } else { + set list1 $Collect + set list2 $Variables + } + +# foreach var $Registers { +# set i [lsearch $list1 "\$$var"] +# if {$i != -1} { +# set list1 [lreplace $list1 $i $i] +# lappend list2 "\$$var" +# } +# } + + lappend list2 "All Registers" + set i [lsearch $list1 "All Registers"] + if {$i != -1} { + set list1 [lreplace $list1 $i $i] + } + + return [list $list1 $list2] + } + + # ------------------------------------------------------------------ + # METHOD: change_other - add/remove a user defined type + # ------------------------------------------------------------------ + method change_other {} { + set other [$OtherEntry get] + + if {"$other" != ""} { + set added 0 + + # Check if this is a local/register/arg + set i [lsearch $Locals "$other"] + if {$i != -1} { + set i [lsearch $Collect "$other"] + set added 1 + if {$i != -1} { + # It's a local on the collection list + debug "local on collection list" + set add 0 + set list1 [lreplace $Collect $i $i] + set list2 [concat $Variables "$other"] + } else { + # It's a local on the variables list + debug "local on variable list" + set add 1 + set i [lsearch $Variables "$other"] + set list1 [lreplace $Variables $i $i] + set list2 [concat $Collect "$other"] + } + } + + set i [lsearch $Registers [string trim "$other" \$]] + if {$i != -1} { + set i [lsearch $Collect "$other"] + set added 1 + if {$i != -1} { + # It's a register on the collection list + debug "register on collection list" + set add 0 + set list1 [lreplace $Collect $i $i] + set list2 [concat $Variables "$other"] + } else { + # It's a register on the variables list + debug "register on variable list" + set add 1 + set i [lsearch $Variables "$other"] + set list1 [lreplace $Variables $i $i] + set list2 [concat $Collect "$other"] + } + } + + set i [lsearch $Args $other] + if {$i != -1} { + set i [lsearch $Collect "$other"] + set added 1 + if {$i != -1} { + # It's an arg on the collection list + debug "arg on collection list" + set add 0 + set list1 [lreplace $Collect $i $i] + set list2 [concat $Variables "$other"] + } else { + # It's an arg on the variables list + debug "arg on variable list" + set add 1 + set i [lsearch $Variables "$other"] + set list1 [lreplace $Variables $i $i] + set list2 [concat $Collect "$other"] + } + } + + # Check for special tags + if {!$added} { + if {"[string tolower $other]" == "all locals"} { + set i [lsearch $Variables "All Locals"] + if {$i != -1} { + # It's "All Locals" on the variables list + set add 1 + set lists [all_locals 1] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } else { + # It's "All Locals" on the Collect list + set add 0 + set lists [all_locals 0] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } + } elseif {"[string tolower $other]" == "all registers"} { + set i [lsearch $Variables "All Registers"] + if {$i != -1} { + # It's "All Registers" on the Variables list + set add 1 + set lists [all_regs 1] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } else { + set add 0 + set lists [all_regs 0] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } + } elseif {"[string tolower $other]" == "all arguments"} { + set i [lsearch $Variables "All Arguments"] + if {$i != -1} { + # It's "All Arguments" on the Variables list + set add 1 + set lists [all_args 1] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } else { + set add 0 + set lists [all_args 0] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } + } elseif {"[string tolower $other]" == "collect stack"} { + set i [lsearch $Variables "Collect Stack"] + if {$i != -1} { + # It's "All Arguments" on the Variables list + set add 1 + set lists [all_args 1] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } else { + set add 0 + set lists [all_args 0] + set list1 [lindex $lists 0] + set list2 [lindex $lists 1] + } + } else { + # Check if this entry is on the Collect list + set i [lsearch $Collect $other] + if {$i != -1} { + # It's on the list -- remove it + set add 0 + set list1 [lreplace $Collect $i $i] + set list2 $Variables + } else { + # It's not on the list -- add it + + set other [string trim $other \ \r\t\n] + + # accept everything, send to gdb to validate + set ok 1 + + # memranges will be rejected right here + + if {[string range $other 0 1] == "\$("} { + tk_messageBox -type ok -icon error \ + -message "Expression syntax not supported" + set ok 0 + } + + # do all syntax checking later + if {$ok} { + #debug "Keeping \"$other\"" + # We MUST string out all spaces... + if {[regsub -all { } $other {} expression]} { + set other $expression + } + set add 1 + set list1 $Variables + set list2 [concat $Collect "$other"] + } else { + #debug "Discarding \"$other\"" + } + } + } + } + + # Clear the entry + $OtherEntry delete 0 end + + if {$add} { + set Variables $list1 + set Collect $list2 + } else { + set Variables $list2 + set Collect $list1 + } + fill_listboxes + } + } + + + # ------------------------------------------------------------------ + # METHOD: get_selections - get all the selected variables + # pass 0 to get the selections from the collect box + # Returns a list of: listbox in which the selections were + # obtained, last element selected on the list, and all the + # selected elements + # ------------------------------------------------------------------ + method get_selections {vars} { + + if {$vars} { + set widget $VariablesLB + } else { + set widget $CollectLB + } + + set elements [$widget curselection] + set list {} + set i 0 + foreach i $elements { + lappend list [$widget get $i] + } + + return [list $widget $i $elements] + } + + # ------------------------------------------------------------------ + # METHOD: cancel - cancel the dialog and do not set the trace + # ------------------------------------------------------------------ + method cancel {} { + delete + } + + method remove_special {list items} { + + foreach item $items { + set i [lsearch $list $item] + if {$i != -1} { + set list [lreplace $list $i $i] + } else { + set i [lsearch $list \$$item] + if {$i != -1} { + set list [lreplace $list $i $i] + } + } + } + + return $list + } + + # ------------------------------------------------------------------ + # METHOD: ok - validate the tracepoint and install it + # ------------------------------------------------------------------ + method ok {} { + global _TStepCount + + # Add anything in the OtherEntry + change_other + + # Check that we are collecting data + if {[llength $Collect] == 0} { + # No data! + set msg "No data specified for the given action." + set answer [tk_messageBox -type ok -title "Tracepoint Error" \ + -icon error \ + -message $msg] + case $answer { + cancel { + cancel + } + ok { + return + } + } + } + + set i [lsearch $Collect "All Locals"] + if {$i != -1} { + set data [lreplace $Collect $i $i] + set data [concat $data {$loc}] + + # Remove all the locals from the list + set data [remove_special $data $Locals] + } else { + set data $Collect + } + + set i [lsearch $data "All Registers"] + if {$i != -1} { + set data [lreplace $data $i $i] + set data [concat $data {$reg}] + + # Remove all the locals from the list + set data [remove_special $data $Registers] + } + + set i [lsearch $data "All Arguments"] + if {$i != -1} { + set data [lreplace $data $i $i] + set data [concat $data {$arg}] + + # Remove all the locals from the list + set data [remove_special $data $Args] + } + + set i [lsearch $data "Collect Stack"] + if {$i != -1} { + set data [lreplace $data $i $i] + set data [concat $data [collect_stack]] + + } + + # Remove repeats + set d {} + foreach i $data { + if {![info exists check($i)]} { + set check($i) 1 + lappend d $i + } + } + + if {$WhileStepping} { + set steps $_TStepCount + } else { + set steps 0 + } + + if {"$Data" != {}} { + set command "modify" + } else { + set command "add" + } + + debug "DATA = $data" + eval $Callback $command $steps [list $data] + delete + } + + + method collect_stack {} { + return $StackCollect + } + + method cmd {line} { + $line + } + + # PUBLIC DATA + public File + public Line {} + public WhileStepping 0 + public Number + public Callback + public Data {} + public Steps {} + public Address {} + + # PROTECTED DATA + protected WhileSteppingEntry + protected CollectLB + protected VariablesLB + protected Variables {} + protected Collect {} + protected Locals + protected Args + protected Registers + protected Others {} + protected AddButton + protected RemoveButton + protected OtherEntry + protected StackCollect {*(char*)$sp@64} +} diff --git a/gdb/gdbtk/library/attachdlg.itb b/gdb/gdbtk/library/attachdlg.itb new file mode 100644 index 00000000000..8d066171b21 --- /dev/null +++ b/gdb/gdbtk/library/attachdlg.itb @@ -0,0 +1,218 @@ +# +# attachdlg.itb - itcl implementations for class AttachDlg +# ---------------------------------------------------------------------- +# Implements Attach to process window... +# +# ---------------------------------------------------------------------- +# Copyright (C) 1999 Cygnus Solutions +# + +body AttachDlg::constructor {args} { + + build_win + eval itk_initialize $args + +} + +body AttachDlg::build_win {} { + + # CHOOSE_PID: the list box with list or processes. Also an entry + # for typing in the PID by hand. + + itk_component add choose_pid { + iwidgets::scrolledlistbox $itk_interior.cpid -visibleitems 30x15 \ + -labeltext "Choose process" -labelpos nw \ + -labelrelief groove -labelborderwidth 2 \ + -ipadx 8 -ipady 6 -childsitepos s -hscrollmode none \ + -textbackground white -exportselection 0 \ + -selectioncommand [code $this select_pid] \ + -dblclickcommand [code $this doit] + } + + itk_component add pid_filter { + iwidgets::entryfield [$itk_component(choose_pid) childsite].filt \ + -labeltext Filter: -textbackground white \ + -focuscommand [code $this clear_pid_selection] \ + -command [code $this filter_pid_selection] + } + + itk_component add pid_sep { + frame [$itk_component(choose_pid) childsite].sep \ + -height 2 -borderwidth 1 -relief sunken + } + + # PID_ENTRY: this is the PID entry box. You can enter the pid + # by hand here, or click on the listbox to have it entered for you. + + itk_component add pid_entry { + iwidgets::entryfield [$itk_component(choose_pid) childsite].lab \ + -labeltext PID: -validate numeric -textbackground white \ + -focuscommand [code $this clear_pid_selection] + } + pack $itk_component(pid_filter) -fill x -side top -pady 4 + pack $itk_component(pid_sep) -fill x -side top -pady 8 + pack $itk_component(pid_entry) -fill x -side bottom -pady 4 + + + itk_component add symbol_label { + iwidgets::labeledframe $itk_interior.sym -labeltext "Choose Exec file" \ + -labelpos nw -labelrelief groove -labelborderwidth 2 \ + -ipadx 8 -ipady 6 + } + + itk_component add symbol_file { + iwidgets::entryfield [$itk_interior.sym childsite].f -labeltext File: \ + -textbackground white + } + pack $itk_component(symbol_file) -pady 4 -padx 4 -fill x + # can't use the -state in the entryfield, 'cause that affects the + # label as well... + $itk_component(symbol_file) component entry configure -state disabled + + $itk_component(symbol_file) configure -state normal + $itk_component(symbol_file) insert 0 $::gdb_exe_name + $itk_component(symbol_file) configure -state disabled + + itk_component add symbol_browse { + button [$itk_component(symbol_file) childsite].br -text Choose... \ + -command [code $this choose_symbol_file] + } + pack $itk_component(symbol_browse) -pady 4 -padx 4 -ipadx 4 + + itk_component add button_box { + frame $itk_interior.b + } + + itk_component add cancel { + button $itk_component(button_box).cancel -text Cancel \ + -command [code $this cancel] + } + + itk_component add ok { + button $itk_component(button_box).ok -text OK -command [code $this doit] + } + + if {$::gdb_exe_name == ""} { + $itk_component(ok) configure -state disabled + } + + ::standard_button_box $itk_component(button_box) + + pack $itk_component(button_box) -side bottom -fill x \ + -pady 4 -padx 4 + pack $itk_component(choose_pid) -fill both -expand 1 -pady 4 -padx 4 + pack $itk_component(symbol_label) -fill x -pady 4 -padx 4 + + after idle [list update idletasks; $this list_pids] + +} + +# ------------------------------------------------------------------ +# METHOD: doit - This accepts the attach command. +# ------------------------------------------------------------------ + +body AttachDlg::doit {} { + set AttachDlg::last_button 1 + set AttachDlg::last_pid [$itk_component(pid_entry) get] + set AttachDlg::symbol_file [$itk_component(symbol_file) get] + debug "About to unpost" + unpost +} + +# ------------------------------------------------------------------ +# METHOD: cancel - unpost the dialog box without attaching. +# ------------------------------------------------------------------ + +body AttachDlg::cancel {} { + set AttachDlg::last_button 0 + set AttachDlg::last_pid {} + unpost +} + +# ------------------------------------------------------------------ +# METHOD: choose_symbol_file - Query for a new symbol file. +# ------------------------------------------------------------------ + +body AttachDlg::choose_symbol_file {} { + set file [tk_getOpenFile -parent . -title "Load New Executable"] + if {$file != ""} { + $itk_component(symbol_file) configure -state normal + $itk_component(symbol_file) clear + $itk_component(symbol_file) insert 0 $file + $itk_component(symbol_file) configure -state disabled + $itk_component(ok) configure -state active + } +} + + +# ------------------------------------------------------------------ +# METHOD: list_pids - List the available processes. Right now, +# this just spawns ps, which means we have to deal with +# all the different ps flags & output formats. At some +# point we should steal some C code to do it by hand. +# ------------------------------------------------------------------ + +body AttachDlg::list_pids {{expr {}}} { + if {[catch {::open "|ps w" r} psH]} { + set errTxt "Could not exec ps: $psH +You will have to enter the PID by hand." + ManagedWin::open WarningDlg -message [list $errTxt] + return + } + gets $psH header + + set nfields [llength $header] + set nfields_m_1 [expr $nfields - 1] + set regexp {^ *([^ ]*) +} + for {set i 1} {$i < $nfields_m_1} {incr i} { + append regexp {[^ ]* +} + } + append regexp {(.*)$} + + $itk_component(choose_pid) clear + set pid_list {} + + while {[gets $psH line] >= 0} { + regexp $regexp $line dummy PID COMMAND + if {$expr == "" || [regexp $expr $COMMAND dummy]} { + lappend pid_list [list $PID $COMMAND] + $itk_component(choose_pid) insert end $COMMAND + } + } + + close $psH + $itk_component(choose_pid) selection set 0 + select_pid + +} + +# ------------------------------------------------------------------ +# METHOD: select_pid - Grab the selected element from the PID listbox +# and insert the associated PID into the entry form. +# ------------------------------------------------------------------ + +body AttachDlg::select_pid {} { + set hit [$itk_component(choose_pid) curselection] + if {$hit != ""} { + $itk_component(pid_entry) clear + $itk_component(pid_entry) insert 0 [lindex [lindex $pid_list $hit] 0] + } +} + +# ------------------------------------------------------------------ +# METHOD: clear_pid_selection - Clear the current PID selection. +# ------------------------------------------------------------------ + +body AttachDlg::clear_pid_selection {} { + $itk_component(choose_pid) selection clear 0 end + $itk_component(pid_entry) selection range 0 end +} + +# ------------------------------------------------------------------ +# METHOD: filter_pid_selection - Filters the pid box. +# ------------------------------------------------------------------ + +body AttachDlg::filter_pid_selection {} { + + list_pids [$itk_component(pid_filter) get] +} diff --git a/gdb/gdbtk/library/attachdlg.ith b/gdb/gdbtk/library/attachdlg.ith new file mode 100644 index 00000000000..b0b6a1131af --- /dev/null +++ b/gdb/gdbtk/library/attachdlg.ith @@ -0,0 +1,35 @@ +# +# attachdlg.ith - itcl declarations for class AttachDlg +# ---------------------------------------------------------------------- +# Implements Attach to process window +# +# ---------------------------------------------------------------------- +# Copyright (C) 1999 Cygnus Solutions +# +class AttachDlg { + inherit ModalDialog ManagedWin + + public { + method constructor {args} + proc last_button {} {return $last_button} + proc pid {} {return $last_pid} + proc symbol_file {} {return $symbol_file} + } + + protected { + method build_win {args} + method cancel {} + method choose_symbol_file {} + method doit {} + method list_pids {{expr {}}} + method select_pid {} + method clear_pid_selection {} + method filter_pid_selection {} + + variable pid_list + + common last_button 0 + common last_pid {} + common symbol_file + } +} diff --git a/gdb/gdbtk/library/blockframe.itb b/gdb/gdbtk/library/blockframe.itb new file mode 100644 index 00000000000..2076f5dfc65 --- /dev/null +++ b/gdb/gdbtk/library/blockframe.itb @@ -0,0 +1,227 @@ +# Block and frame class implementations for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# ------------------------------------------------------------------ +# Block +# ------------------------------------------------------------------ +body Block::constructor {start end args} { + + # Record runtime info about this block + set _start $start + set _end $end + set _variables [_findVariables] + eval configure $args +} + +# Destroy ourself. +body Block::destructor {} { + + # Each block is responsible for destroying its + # variables and removing them from the list of + # of all variables for this frame + foreach var $_variables { + $var delete + } +} + +# Return a list of variables defined in this block +# This list is determined when we are created. +body Block::variables {} { + return $_variables +} + +# Find the new variables for this block. +body Block::_findVariables {} { + + # Find the new variables for this block. + set variables [gdb_block_variables $_start $_end] + + # Create variables. + set vars {} + foreach variable $variables { + # Be paranoid: catch errors constructing variable. + set err [catch {gdb_variable create -expr $variable} obj] + if {!$err} { + lappend vars $obj + } + } + + return $vars +} + +body Block::update {} { + + set changed {} + foreach var $_variables { + set changed [concat $changed [$var update]] + } + + return $changed +} + +body Block::info {} { + + return [list $_start $_end] +} + +# ------------------------------------------------------------------ +# Frame +# ------------------------------------------------------------------ +body Frame::constructor {addr} { + + set _addr $addr + + # Create all blocks in the selected frame + set _blocks {} + _createBlocks [gdb_get_blocks] + +} + +body Frame::destructor {} { + # destroy our own blocks + foreach block $_blocks { + _removeBlock $block + } +} + +body Frame::_removeBlock {blockObj} { + + set i [lsearch $_blocks $blockObj] + if {$i != -1} { + set _blocks [lreplace $_blocks $i $i] + delete object $blockObj + } +} + +body Frame::_addBlock {block} { + + set start [lindex $block 0] + set end [lindex $block 1] + set b [Block \#auto $start $end] + lappend _blocks $b + + return $b +} + +body Frame::_createBlocks {blocks} { + + foreach block $blocks { + set b [_addBlock $block] + } +} + +body Frame::update {} { + + set vars {} + foreach block $_blocks { + set vars [concat $vars [$block update]] + } + + return $vars +} + +body Frame::variables {} { + + set vars {} + foreach block $_blocks { + set vars [concat $vars [$block variables]] + } + + return $vars +} + +body Frame::new {} { + # find any new variables. So get a list of all blocks, + # eliminate duplicates, and get those variables. + + set blocks [gdb_get_blocks] + set new {} + + foreach block $blocks { + set b [_findBlock $block] + if {$b == ""} { + # Found a new block. Create it get its variables + set b [_addBlock $block] + set new [concat $new [$b variables]] + } + } + + return $new +} + +body Frame::deleteOld {} { + + foreach block [_oldBlocks] { + _removeBlock $block + } +} + +body Frame::_oldBlocks {} { + + set blocks [gdb_get_blocks] + set oldObjs $_blocks + + foreach block $blocks { + set obj [_findBlock $block] + if {$obj != ""} { + # Found it.. Remove it from old + set i [lsearch $oldObjs $obj] + set oldObjs [lreplace $oldObjs $i $i] + } + } + + return $oldObjs +} + +body Frame::old {} { + + # All the variables in the blocks in old are now gone... + # We don't remove blocks here, since the frontend viewer + # might want to keep these variables around for a little while + # longer. + set vars {} + set old [_oldBlocks] + foreach block $old { + set vars [concat $vars [$block variables]] + } + + return $vars +} + +body Frame::_findBlock {block} { + + foreach b $_blocks { + set info [$b info] + if {$info == $block} { + return $b + } + } + + return "" +} + +body Frame::_findBlockIndex {block} { + + set i 0 + foreach b $_blocks { + set info [$b info] + if {$info == $block} { + return $i + } + incr i + } + + return -1 +} + + diff --git a/gdb/gdbtk/library/blockframe.ith b/gdb/gdbtk/library/blockframe.ith new file mode 100644 index 00000000000..a147f7c60a7 --- /dev/null +++ b/gdb/gdbtk/library/blockframe.ith @@ -0,0 +1,63 @@ +# Class definitions for blocks and frames for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +class Block { + + public { + method constructor {start end args} + method destructor {} + method variables {} + method update {} + method info {} + } + + private { + # Start and end address for this block + variable _start + variable _end + + # List of variables (new) variables defined in this block + variable _variables + + method _findVariables {} + } +} + +class Frame { + + public { + method constructor {addr} + method destructor {} + method variables {} + method update {} + method new {} + method old {} + method deleteOld {} + method address {} { return $_addr } + } + + private { + method _createBlocks {blocks} + method _addBlock {block} + method _findBlock {block} + method _findBlockIndex {block} + method _removeBlock {blockObj} + method _oldBlocks {} + + # Our address + variable _addr + + # A list of all blocks + variable _blocks + } +} diff --git a/gdb/gdbtk/library/bpwin.itb b/gdb/gdbtk/library/bpwin.itb new file mode 100644 index 00000000000..17f85c05dc0 --- /dev/null +++ b/gdb/gdbtk/library/bpwin.itb @@ -0,0 +1,697 @@ +# Breakpoint window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ------------------------------------------------------------------ +# CONSTRUCTOR: create the main breakpoint window +# ------------------------------------------------------------------ +body BpWin::constructor {args} { + window_name "Breakpoints" "BPs" + + add_hook gdb_breakpoint_change_hook "$this update" + if {[pref getd gdb/bp/menu] != ""} { + set mbar 0 + } + set show_threads [pref get gdb/bp/show_threads] + debug "Ready to build" + build_win + eval itk_initialize $args + debug "done building" +} + +# ------------------------------------------------------------------ +# DESTRUCTOR: destroy the breakpoint window +# ------------------------------------------------------------------ +body BpWin::destructor {} { + remove_hook gdb_breakpoint_change_hook "$this update" +} + + +# ------------------------------------------------------------------ +# METHOD: build_win - build the main breakpoint window +# ------------------------------------------------------------------ +body BpWin::build_win {} { + global _bp_en _bp_disp tixOption tcl_platform + set bg1 $tixOption(input1_bg) + + frame $itk_interior.f -bg $bg1 + if {$tcl_platform(platform) == "windows"} { + tixScrolledWindow $itk_interior.f.sw -scrollbar both -sizebox 1 + } else { + tixScrolledWindow $itk_interior.f.sw -scrollbar auto + } + set twin [$itk_interior.f.sw subwidget window] + $twin configure -bg $bg1 + + # write header + if {$tracepoints} { + label $twin.num0 -text "Num" -relief raised -bd 2 -anchor center \ + -font src-font + } + label $twin.thread0 -text "Thread" -relief raised -bd 2 -anchor center \ + -font src-font + label $twin.addr0 -text "Address" -relief raised -bd 2 -anchor center \ + -font src-font + label $twin.file0 -text "File" -relief raised -bd 2 -anchor center \ + -font src-font + label $twin.line0 -text "Line" -relief raised -bd 2 -anchor center \ + -font src-font + label $twin.func0 -text "Function" -relief raised -bd 2 -anchor center \ + -font src-font + + if {$tracepoints} { + label $twin.pass0 -text "PassCount" -relief raised -borderwidth 2 \ + -anchor center -font src-font + grid x $twin.num0 $twin.addr0 $twin.file0 $twin.line0 $twin.func0 $twin.pass0 \ + -sticky new + } else { + if {$show_threads} { + grid x $twin.thread0 $twin.addr0 $twin.file0 $twin.line0 $twin.func0 -sticky new + # Let the File and Function columns expand; no others. + grid columnconfigure $twin 3 -weight 1 + grid columnconfigure $twin 5 -weight 1 + } else { + grid x $twin.addr0 $twin.file0 $twin.line0 $twin.func0 -sticky new + # Let the File and Function columns expand; no others. + grid columnconfigure $twin 2 -weight 1 + grid columnconfigure $twin 4 -weight 1 + } + } + + + # The last row must always suck up all the leftover vertical + # space. + set next_row 1 + grid rowconfigure $twin $next_row -weight 1 + + if { $mbar } { + menu $itk_interior.m -tearoff 0 + [winfo toplevel $itk_interior] configure -menu $itk_interior.m + if { $tracepoints == 0 } { + $itk_interior.m add cascade -menu $itk_interior.m.bp -label "Breakpoint" -underline 0 + } else { + $itk_interior.m add cascade -menu $itk_interior.m.bp -label "Tracepoint" -underline 0 + } + set m [menu $itk_interior.m.bp] + if { $tracepoints == 0 } { + $m add radio -label "Normal" -variable _bp_disp($selected) \ + -value donttouch -underline 0 -state disabled + $m add radio -label "Temporary" -variable _bp_disp($selected) \ + -value delete -underline 0 -state disabled + } else { + $m add command -label "Actions" -underline 0 -state disabled + } + + $m add separator + $m add radio -label "Enabled" -variable _bp_en($selected) -value 1 \ + -underline 0 -state disabled + $m add radio -label "Disabled" -variable _bp_en($selected) -value 0 \ + -underline 0 -state disabled + $m add separator + $m add command -label "Remove" -underline 0 -state disabled + $itk_interior.m add cascade -menu $itk_interior.m.all -label "Global" \ + -underline 0 + set m [menu $itk_interior.m.all] + $m add check -label " Show Threads" \ + -variable [pref varname gdb/bp/show_threads] \ + -underline 1 -command "$this toggle_threads" + $m add separator + $m add command -label "Disable All" -underline 0 \ + -command "$this bp_all disable" + $m add command -label "Enable All" -underline 0 \ + -command "$this bp_all enable" + $m add separator + $m add command -label "Remove All" -underline 0 \ + -command "$this bp_all delete" + $m add separator + $m add command -label "Store Breakpoints..." -underline 0 \ + -command [code $this bp_store] + $m add command -label "Restore Breakpoints..." -underline 3 \ + -command [code $this bp_restore] + } + + set Menu [menu $itk_interior.pop -tearoff 0] + + if { $tracepoints == 0 } { + $Menu add radio -label "Normal" -variable _bp_disp($selected) \ + -value donttouch -underline 0 + $Menu add radio -label "Temporary" -variable _bp_disp($selected) \ + -value delete -underline 0 + } else { + $Menu add command -label "Actions" -underline 0 + } + $Menu add separator + $Menu add radio -label "Enabled" -variable _bp_en($selected) -value 1 -underline 0 + $Menu add radio -label "Disabled" -variable _bp_en($selected) -value 0 -underline 0 + $Menu add separator + $Menu add command -label "Remove" -underline 0 + $Menu add cascade -menu $Menu.all -label "Global" -underline 0 + set m [menu $Menu.all] + $m add check -label " Show Threads" -variable [pref varname gdb/bp/show_threads] \ + -underline 1 -command "$this toggle_threads" + $m add separator + $m add command -label "Disable All" -underline 0 -command "$this bp_all disable" + $m add command -label "Enable All" -underline 0 -command "$this bp_all enable" + $m add separator + $m add command -label "Remove All" -underline 0 -command "$this bp_all delete" + + if { $tracepoints == 0 } { + # insert all breakpoints + foreach i [gdb_get_breakpoint_list] { + bp_add $i + } + } else { + # insert all tracepoints + foreach i [gdb_get_tracepoint_list] { + bp_add $i 1 + } + } + + pack $itk_interior.f.sw -side left -expand true -fill both + pack $itk_interior.f -side top -expand true -fill both + +} + +# ------------------------------------------------------------------ +# METHOD: bp_add - add a breakpoint entry +# ------------------------------------------------------------------ +body BpWin::bp_add { bpnum {tracepoint 0}} { + global _bp_en _bp_disp tcl_platform _files + + if {$tracepoint} { + set bpinfo [gdb_get_tracepoint_info $bpnum] + lassign $bpinfo file func line pc enabled pass_count \ + step_count thread hit_count actions + set disposition tracepoint + set bptype tracepoint + } else { + set bpinfo [gdb_get_breakpoint_info $bpnum] + lassign $bpinfo file func line pc type enabled disposition \ + ignore_count commands cond thread hit_count + set bptype breakpoint + } + + debug "bp_add bpnum=$bpnum thread=$thread show=$show_threads" + set i $next_row + set _bp_en($i) $enabled + set _bp_disp($i) $disposition + set temp($i) "" + switch $disposition { + donttouch { set color [pref get gdb/src/bp_fg] } + delete { + set color [pref get gdb/src/temp_bp_fg] + set temp($i) delete + } + tracepoint { + set color [pref get gdb/src/trace_fg] + } + default { set color yellow } + } + + if {$thread != "-1"} {set color [pref get gdb/src/thread_fg]} + + if {$tcl_platform(platform) == "windows"} { + checkbutton $twin.en$i -relief flat -variable _bp_en($i) -bg $bg1 \ + -activebackground $bg1 -command "$this bp_able $i" -fg $color + } else { + checkbutton $twin.en$i -relief flat -variable _bp_en($i) -selectcolor $color \ + -command "$this bp_able $i" -bg $bg1 -activebackground $bg1 + } + + if {$tracepoints} { + label $twin.num$i -text "$bpnum " -relief flat -anchor e -font src-font -bg $bg1 + } + label $twin.addr$i -text "$pc " -relief flat -anchor e -font src-font -bg $bg1 + if {[info exists _files(short,$file)]} { + set file $_files(short,$file) + } else { + # FIXME. Really need to do better than this. + set file [::file tail $file] + } + if {$show_threads} { + if {$thread == "-1"} {set thread "ALL"} + label $twin.thread$i -text "$thread " -relief flat -anchor e -font src-font -bg $bg1 + } + label $twin.file$i -text "$file " -relief flat -anchor e -font src-font -bg $bg1 + label $twin.line$i -text "$line " -relief flat -anchor e -font src-font -bg $bg1 + label $twin.func$i -text "$func " -relief flat -anchor e -font src-font -bg $bg1 + + if {$tracepoints} { + label $twin.pass$i -text "$pass_count " -relief flat -anchor e -font src-font -bg $bg1 + } + + if {$mbar} { + set zz [list addr file func line] + if {$tracepoints} {lappend zz num pass} + if {$show_threads} {lappend zz thread} + foreach thing $zz { + bind $twin.${thing}${i} <1> "$this bp_select $i" + bind $twin.${thing}${i} <Double-1> "$this goto_bp $i" + } + } + + if {$tracepoints} { + grid $twin.en$i $twin.num$i $twin.addr$i $twin.file$i $twin.line$i \ + $twin.func$i $twin.pass$i -sticky new -ipadx 4 -ipady 2 + } else { + if {$show_threads} { + grid $twin.en$i $twin.thread$i $twin.addr$i $twin.file$i $twin.line$i \ + $twin.func$i -sticky new -ipadx 4 -ipady 2 + } else { + grid $twin.en$i $twin.addr$i $twin.file$i $twin.line$i \ + $twin.func$i -sticky new -ipadx 4 -ipady 2 + } + } + + # This used to be the last row. Fix it vertically again. + grid rowconfigure $twin $i -weight 0 + + set index_to_bpnum($i) $bpnum + set Index_to_bptype($i) $bptype + incr i + set next_row $i + grid rowconfigure $twin $i -weight 1 +} + +# ------------------------------------------------------------------ +# METHOD: bp_store - stores away the breakpoints in a file of gdb +# commands +# ------------------------------------------------------------------ +body BpWin::bp_store {} { + set out_file [tk_getSaveFile] + if {$out_file == ""} { + return + } + if {[catch {::open $out_file w} outH]} { + tk_messageBox -message "Could not open $out_file: $outH" + return + } + foreach breakpoint [gdb_get_breakpoint_list] { + # This is an lassign + foreach {file function line_no address type \ + enable_p disp ignore cmds thread hit_count} \ + [gdb_get_breakpoint_info $breakpoint] { + break + } + + if {$file != ""} { + set filename [file tail $file] + set bp_specifier $filename:$line_no + } else { + set bp_specifier *$address + } + + if {[string compare $disp "delete"] == 0} { + puts $outH "tbreak $bp_specifier" + } else { + puts $outH "break $bp_specifier" + } + + if {!$enable_p} { + puts $outH "disable \$bpnum" + } + if {$ignore > 0} { + puts $outH "ignore \$bpnum $ignore" + } + } + close $outH +} + +# ------------------------------------------------------------------ +# METHOD: bp_restore - restore the breakpoints from a file of gdb +# commands +# ------------------------------------------------------------------ +body BpWin::bp_restore {} { + set inH [tk_getOpenFile] + if {$inH == ""} { + return + } + bp_all delete + if {[catch {gdb_cmd "source $inH"} err]} { + tk_messageBox -message "Error sourcing in BP file $inH: \"$err\"" + } +} + +# ------------------------------------------------------------------ +# METHOD: bp_select - select a row in the grid +# ------------------------------------------------------------------ +body BpWin::bp_select { r } { + global tixOption _bp_en _bp_disp + + set zz [list addr file func line] + if {$tracepoints} {lappend zz num pass} + if {$show_threads} {lappend zz thread} + + if {$selected} { + set i $selected + + foreach thing $zz { + $twin.${thing}${i} configure -fg $tixOption(fg) -bg $bg1 + bind $twin.${thing}${i} <3> break + } + } + + # if we click on the same line, unselect it and return + if {$selected == $r} { + set selected 0 + + if {$tracepoints == 0} { + $itk_interior.m.bp entryconfigure "Normal" -state disabled + $itk_interior.m.bp entryconfigure "Temporary" -state disabled + } else { + $itk_interior.m.bp entryconfigure "Actions" -state disabled + } + $itk_interior.m.bp entryconfigure "Enabled" -state disabled + $itk_interior.m.bp entryconfigure "Disabled" -state disabled + $itk_interior.m.bp entryconfigure "Remove" -state disabled + + foreach thing $zz { + bind $twin.${thing}${r} <3> break + } + + return + } + + foreach thing $zz { + $twin.${thing}${r} configure -fg $tixOption(select_fg) -bg $tixOption(select_bg) + bind $twin.${thing}${r} <3> "tk_popup $Menu %X %Y" + } + + if {$tracepoints == 0} { + $itk_interior.m.bp entryconfigure "Normal" -variable _bp_disp($r) \ + -command "$this bp_type $r" -state normal + $itk_interior.m.bp entryconfigure "Temporary" -variable _bp_disp($r) \ + -command "$this bp_type $r" -state normal + $Menu entryconfigure "Normal" -variable _bp_disp($r) \ + -command "$this bp_type $r" -state normal + $Menu entryconfigure "Temporary" -variable _bp_disp($r) \ + -command "$this bp_type $r" -state normal + } else { + $itk_interior.m.bp entryconfigure "Actions" -command "$this get_actions $r" -state normal + $Menu entryconfigure "Actions" -command "$this get_actions $r" -state normal + } + $itk_interior.m.bp entryconfigure "Enabled" -variable _bp_en($r) \ + -command "$this bp_able $r" -state normal + $itk_interior.m.bp entryconfigure "Disabled" -variable _bp_en($r) \ + -command "$this bp_able $r" -state normal + $itk_interior.m.bp entryconfigure "Remove" -command "$this bp_remove $r" -state normal + $Menu entryconfigure "Enabled" -variable _bp_en($r) \ + -command "$this bp_able $r" -state normal + $Menu entryconfigure "Disabled" -variable _bp_en($r) \ + -command "$this bp_able $r" -state normal + $Menu entryconfigure "Remove" -command "$this bp_remove $r" -state normal + + set selected $r +} + +# ------------------------------------------------------------------ +# METHOD: bp_modify - modify a breakpoint entry +# ------------------------------------------------------------------ +body BpWin::bp_modify { bpnum {tracepoint 0} } { + global _bp_en _bp_disp tcl_platform _files + + if {$tracepoint} { + set bpinfo [gdb_get_tracepoint_info $bpnum] + lassign $bpinfo file func line pc enabled pass_count \ + step_count thread hit_count actions + set disposition tracepoint + set bptype tracepoint + } else { + set bpinfo [gdb_get_breakpoint_info $bpnum] + lassign $bpinfo file func line pc type enabled disposition \ + ignore_count commands cond thread hit_count + set bptype breakpoint + } + + set found 0 + for {set i 1} {$i < $next_row} {incr i} { + if { $bpnum == $index_to_bpnum($i) + && "$Index_to_bptype($i)" == "$bptype"} { + incr found + break + } + } + + if {!$found} { + debug "ERROR: breakpoint number $bpnum not found!" + return + } + + if {$_bp_en($i) != $enabled} { + set _bp_en($i) $enabled + } + + if {$_bp_disp($i) != $disposition} { + set _bp_disp($i) $disposition + } + + switch $disposition { + donttouch { set color [pref get gdb/src/bp_fg] } + delete { + set color [pref get gdb/src/temp_bp_fg] + } + tracepoint { set color [pref get gdb/src/trace_fg] } + default { set color yellow} + } + + if {$thread != "-1"} {set color [pref get gdb/src/thread_fg]} + + if {$tcl_platform(platform) == "windows"} then { + $twin.en$i configure -fg $color + } else { + $twin.en$i configure -selectcolor $color + } + if {$tracepoints} { + $twin.num$i configure -text "$bpnum " + } + $twin.addr$i configure -text "$pc " + if {[info exists _files(short,$file)]} { + set file $_files(short,$file) + } else { + # FIXME. Really need to do better than this. + set file [::file tail $file] + } + if {$show_threads} { + if {$thread == "-1"} {set thread "ALL"} + $twin.thread$i configure -text "$thread " + } + $twin.file$i configure -text "$file " + $twin.line$i configure -text "$line " + $twin.func$i configure -text "$func " + if {$tracepoints} { + $twin.pass$i configure -text "$pass_count " + } +} + +# ------------------------------------------------------------------ +# METHOD: bp_able - enable/disable a breakpoint +# ------------------------------------------------------------------ +body BpWin::bp_able { i } { + global _bp_en + + bp_select $i + + switch $Index_to_bptype($i) { + breakpoint {set type {}} + tracepoint {set type "tracepoint"} + } + + if {$_bp_en($i) == "1"} { + set command "enable $type $temp($i) " + } else { + set command "disable $type " + } + + append command "$index_to_bpnum($i)" + gdb_cmd "$command" +} + +# ------------------------------------------------------------------ +# METHOD: bp_remove - remove a breakpoint +# ------------------------------------------------------------------ +body BpWin::bp_remove { i } { + + bp_select $i + + switch $Index_to_bptype($i) { + breakpoint { set type {} } + tracepoint { set type "tracepoint" } + } + + gdb_cmd "delete $type $index_to_bpnum($i)" +} + +# ------------------------------------------------------------------ +# METHOD: bp_type - change the breakpoint type (disposition) +# ------------------------------------------------------------------ +body BpWin::bp_type { i } { + + if {$Index_to_bptype($i) != "breakpoint"} { + return + } + + set bpnum $index_to_bpnum($i) + #debug "bp_type $i $bpnum" + set bpinfo [gdb_get_breakpoint_info $bpnum] + lassign $bpinfo file func line pc type enabled disposition \ + ignore_count commands cond thread hit_count + bp_select $i + switch $disposition { + delete { + gdb_cmd "delete $bpnum" + gdb_cmd "break *$pc" + } + donttouch { + gdb_cmd "delete $bpnum" + gdb_cmd "tbreak *$pc" + } + default { debug "Unknown breakpoint disposition: $disposition" } + } +} + +# ------------------------------------------------------------------ +# METHOD: bp_delete - delete a breakpoint +# ------------------------------------------------------------------ +body BpWin::bp_delete { bpnum } { + for {set i 1} {$i < $next_row} {incr i} { + if { $bpnum == $index_to_bpnum($i) } { + if {$tracepoints} { + grid forget $twin.en$i $twin.num$i $twin.addr$i $twin.file$i \ + $twin.line$i $twin.func$i $twin.pass$i + destroy $twin.en$i $twin.num$i $twin.addr$i $twin.file$i \ + $twin.line$i $twin.func$i $twin.pass$i + } else { + if {$show_threads} { + grid forget $twin.thread$i + destroy $twin.thread$i + } + grid forget $twin.en$i $twin.addr$i $twin.file$i $twin.line$i $twin.func$i + destroy $twin.en$i $twin.addr$i $twin.file$i $twin.line$i $twin.func$i + } + if {$selected == $i} { + set selected 0 + } + return + } + } +} + +# ------------------------------------------------------------------ +# METHOD: update - update widget when a breakpoint changes +# ------------------------------------------------------------------ +body BpWin::update {action bpnum addr {linenum {}} {file {}} {type 0} args} { + #debug "bp update $action $bpnum $type" + + if {$type == "tracepoint"} { + set tp 1 + } else { + set tp 0 + } + + switch $action { + modify { bp_modify $bpnum $tp} + create { bp_add $bpnum $tp} + delete { bp_delete $bpnum } + default { debug "Unknown breakpoint action: $action" } + } +} + +# ------------------------------------------------------------------ +# METHOD: bp_all - perform a command on all breakpoints +# ------------------------------------------------------------------ +body BpWin::bp_all { command } { + + if {!$tracepoints} { + # Do all breakpoints + foreach bpnum [gdb_get_breakpoint_list] { + if { $command == "enable"} { + for {set i 1} {$i < $next_row} {incr i} { + if { $bpnum == $index_to_bpnum($i) + && "$Index_to_bptype($i)" == "breakpoint"} { + gdb_cmd "enable $temp($i) $bpnum" + break + } + } + } else { + gdb_cmd "$command $bpnum" + } + } + } else { + # Do all tracepoints + foreach bpnum [gdb_get_tracepoint_list] { + if { $command == "enable"} { + for {set i 1} {$i < $next_row} {incr i} { + if { $bpnum == $index_to_bpnum($i) + && "$Index_to_bptype($i)" == "tracepoint"} { + gdb_cmd "enable tracepoint $bpnum" + break + } + } + } else { + gdb_cmd "$command tracepoint $bpnum" + } + } + } +} + +# ------------------------------------------------------------------ +# METHOD: get_actions - pops up the add trace dialog on a selected +# tracepoint +# ------------------------------------------------------------------ +body BpWin::get_actions {bpnum} { + set bpnum $index_to_bpnum($bpnum) + set bpinfo [gdb_get_tracepoint_info $bpnum] + lassign $bpinfo file func line pc enabled pass_count \ + step_count thread hit_count actions + + set filename [::file tail $file] + ManagedWin::open TraceDlg -File $filename -Lines $line +} + +# ------------------------------------------------------------------ +# METHOD: toggle_threads - callback when show_threads is toggled +# ------------------------------------------------------------------ +body BpWin::toggle_threads {} { + set show_threads [pref get gdb/bp/show_threads] + reconfig +} + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body BpWin::reconfig {} { + if {[winfo exists $itk_interior.f]} { destroy $itk_interior.f } + if {[winfo exists $itk_interior.m]} { destroy $itk_interior.m } + if {[winfo exists $itk_interior.pop]} { destroy $itk_interior.pop } + build_win +} + +# ------------------------------------------------------------------ +# METHOD: goto_bp - show bp in source window +# ------------------------------------------------------------------ +body BpWin::goto_bp {r} { + set bpnum $index_to_bpnum($r) + if {$tracepoints} { + set bpinfo [gdb_get_tracepoint_info $bpnum] + } else { + set bpinfo [gdb_get_breakpoint_info $bpnum] + } + set pc [lindex $bpinfo 3] + + # !! FIXME: multiple source windows? + set src [lindex [ManagedWin::find SrcWin] 0] + set info [gdb_loc *$pc] + $src location BROWSE_TAG $info +} + + diff --git a/gdb/gdbtk/library/bpwin.ith b/gdb/gdbtk/library/bpwin.ith new file mode 100644 index 00000000000..d3b56f893ab --- /dev/null +++ b/gdb/gdbtk/library/bpwin.ith @@ -0,0 +1,56 @@ +# Breakpoint window class definition for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class BpWin { + inherit EmbeddedWin GDBWin + + public { + variable tracepoints 0 + + method constructor {args} + method destructor {} + method bp_select {r} + method bp_able { i } + method bp_remove { i } + method bp_restore {} + method bp_store {} + method bp_type { i } + method update {action bpnum addr {linenum {}} {file {}} {type 0} args} + method bp_all { command } + method get_actions {bpnum} + method toggle_threads {} + method reconfig {} + method goto_bp {r} + + } + + private { + variable twin + variable next_row 0 + variable index_to_bpnum + variable Index_to_bptype + variable temp + variable mbar 1 + variable selected 0 + variable bg1 + variable Menu + variable show_threads ;#cached copy of [pref get gdb/bp/show_threads] + + method build_win {} + method bp_add { bpnum {tracepoint 0}} + method bp_modify { bpnum {tracepoint 0} } + method bp_delete { bpnum } + } + +} diff --git a/gdb/gdbtk/library/browserwin.itb b/gdb/gdbtk/library/browserwin.itb new file mode 100644 index 00000000000..0b4ff2e177e --- /dev/null +++ b/gdb/gdbtk/library/browserwin.itb @@ -0,0 +1,925 @@ +# Browswer window for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements Browser window for gdb +# +# ---------------------------------------------------------------------- + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new browser window +# ------------------------------------------------------------------ + +option add *BrowserWin.textBackground white + +body BrowserWin::constructor {args} { + #eval itk_initialize $args + window_name "Function Browser" + + set Current(filename) {} + set Current(function) {} + _build_win + + eval itk_initialize $args + + # Create the toplevel binding for this class + bind Configure_Browser_$this <Configure> [code $this _resize] + + add_hook file_changed_hook [code $this _fill_file_box] +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body BrowserWin::destructor {} { + + if {$resize_after != ""} { + after cancel $resize_after + } + if {$filter_trace_after != ""} { + after cancel $filter_trace_after + } + + if {$MoreVisible} { + pref set gdb/browser/view_is_open 1 + } else { + pref set gdb/browser/view_is_open 0 + } + + remove_hook file_changed_hook [code $this _fill_file_box] + trace vdelete [pref varname gdb/search/last_symbol] \ + w [code $this _filter_trace_proc] +} + +# ------------------------------------------------------------------ +# METHOD: _build_win - build the main browser window +# ------------------------------------------------------------------ +body BrowserWin::_build_win {} { + global PREFS_state gdb_ImageDir + + # Three frames: regexp, listboxes, and drop-down pane + + itk_component add filter { + iwidgets::labeledframe $itk_interior.filter -labeltext "Filter" \ + -labelrelief groove -labelborderwidth 2 -ipadx 6 -ipady 4 + } + + append labelUpdateCode [$itk_component(filter) clientHandlesConfigure 1] "\n" + + itk_component add browser { + frame $itk_interior.browser + } + + itk_component add view { + frame $itk_interior.view + } + + # Set up the contents of the Filter frame + + itk_component add filt_label { + label [$itk_component(filter) childsite].lbl -text {Show if function } \ + -font src-font + } + + itk_component add filt_type { + combobox::combobox [$itk_component(filter) childsite].type -height 4 \ + -width 15 -editable 0 \ + -command [code $this _set_filter_mode] \ + -font src-font + } { } + + # Fill the filter mode combo-box + + foreach elem $filter_modes { + $itk_component(filt_type) list insert end $elem + } + + set cur_filter_mode [pref get gdb/search/filter_mode] + if {[lsearch $filter_modes $cur_filter_mode] < 0} { + set cur_filter_mode [lindex $filter_modes 0] + } + $itk_component(filt_type) entryset $cur_filter_mode + + itk_component add filt_entry { + entry [$itk_component(filter) childsite].ent -font src-font \ + -textvariable [pref varname gdb/search/last_symbol] -background white + } { + usual Entry + rename -background -textbackground textBackground Background + } + + # Watch keystrokes into the entry box and filter on them... + + trace variable [pref varname gdb/search/last_symbol] w \ + [code $this _filter_trace_proc] + + pack $itk_component(filt_label) -side left + pack $itk_component(filt_type) -side left -padx 4 -fill y -pady 5 + pack $itk_component(filt_entry) -side right -fill both -expand 1 \ + -padx 6 -pady 5 + + # Files Listbox for the Browser frame + itk_component add file_box { + iwidgets::scrolledlistbox $itk_component(browser).files \ + -selectmode extended -exportselection false \ + -labeltext "Files" -labelpos nw -labelrelief groove \ + -labelborderwidth 2 -ipadx 8 -ipady 6 \ + -childsitepos s -hscrollmode none -textbackground white + } + + append labelUpdateCode [$itk_component(file_box) clientHandlesConfigure 1] \ + "\n" + + bind [$itk_component(file_box) component listbox] <ButtonRelease-1> \ + [code $this _process_file_selection %y] + + itk_component add file_sep { + frame [$itk_component(file_box) childsite].sep -relief raised -height 2 \ + -borderwidth 1 + } + + itk_component add file_hide { + checkbutton [$itk_component(file_box) childsite].hide \ + -text {Hide .h files} \ + -variable [pref varname gdb/browser/hide_h] \ + -command [code $this _file_hide_h] + } + + itk_component add file_all { + button [$itk_component(file_box) childsite].sel \ + -text {Select All} -width 12 \ + -command [code $this _select 1] + } + + # Pack the file box in, and grid in the separate bits of the child-site. + + pack $itk_component(file_box) -side left -fill both -expand yes \ + -padx 5 -pady 5 + + grid $itk_component(file_sep) -column 0 -row 0 -columnspan 2 \ + -sticky ew -pady 8 + grid $itk_component(file_hide) -column 0 -row 1 -padx 5 -sticky w + grid $itk_component(file_all) -column 1 -row 1 -padx 5 -sticky e + + grid columnconfigure [$itk_component(file_box) childsite] 0 -weight 1 + + # Functions Listbox for the Browser frame + + itk_component add func_box { + iwidgets::scrolledlistbox $itk_component(browser).funcs \ + -selectmode extended \ + -exportselection false \ + -labeltext "Functions" -labelpos nw -labelrelief groove \ + -labelborderwidth 2 -ipadx 8 -ipady 6 \ + -childsitepos s -hscrollmode none -textbackground white + } + + append labelUpdateCode [$itk_component(func_box) clientHandlesConfigure 1] \ + "\n" + + bind [$itk_component(func_box) component listbox] <ButtonRelease-1> \ + [code $this _process_func_selection %y] + + itk_component add func_sep { + frame [$itk_component(func_box) childsite].sep -relief raised \ + -height 2 -borderwidth 1 + } + + itk_component add func_bp_label { + label [$itk_component(func_box) childsite].bpl -text {Breakpoints:} + } + + itk_component add func_add_bp { + button [$itk_component(func_box) childsite].abp -text {Set} \ + -command [code $this do_all_bp 1] + } + + itk_component add func_remove_bp { + button [$itk_component(func_box) childsite].rbp -text {Delete} \ + -command [code $this do_all_bp 0] + } + + # Pack in the Function box, and grid in the bits of the child-site + + pack $itk_component(func_box) -side right -fill both -expand yes \ + -padx 5 -pady 5 + + grid $itk_component(func_sep) -row 0 -column 0 -columnspan 3 \ + -sticky ew -pady 8 + grid $itk_component(func_bp_label) -row 1 -column 0 -padx 5 + grid $itk_component(func_remove_bp) -row 1 -column 1 -padx 5 + grid $itk_component(func_add_bp) -row 1 -column 2 -padx 5 + + grid columnconfigure [$itk_component(func_box) childsite] 1 -weight 1 + grid columnconfigure [$itk_component(func_box) childsite] 2 -weight 1 + + # "More" frame for viewing source + + if {[lsearch [image names] _MORE_] == -1} { + image create photo _MORE_ -file [file join $gdb_ImageDir more.gif] + image create photo _LESS_ -file [file join $gdb_ImageDir less.gif] + } + + itk_component add view_vis { + frame $itk_interior.view.visible + } + + itk_component add view_more { + button $itk_component(view_vis).btn -image _MORE_ -relief flat \ + -command [code $this _toggle_more] + } + + itk_component add view_label { + label $itk_component(view_vis).lbl -text {View Source} + } + + itk_component add view_sep { + frame $itk_component(view_vis).sep -relief raised -borderwidth 1 -height 2 + } + + pack $itk_component(view_more) -side left -padx 10 -pady 10 + pack $itk_component(view_label) -side left -padx 10 -pady 10 + pack $itk_component(view_sep) -padx 4 -pady 10 -fill x -expand 1 + + grid columnconfigure $itk_component(view_vis) 2 -weight 1 + + pack $itk_component(view_vis) -side top -fill x -expand yes + + # Key bindings for "visible" frames + bind_plain_key $itk_component(filt_entry) Return [list $this search] + bind $itk_component(func_box) <3> [code $this _toggle_bp %y] + + # Construct hidden frame + + itk_component add view_hidden { + frame $itk_interior.hidden + } + + itk_component add view_src { + SrcTextWin $itk_component(view_hidden).src -Tracing 0 \ + -parent $this -ignore_var_balloons 1 + } { + rename -background -textbackground textBackground Background + } + + $itk_component(view_src) configure -textheight 2i + + itk_component add view_bottom { + frame $itk_component(view_hidden).bottom + } + + itk_component add view_name { + label $itk_component(view_hidden).name -font src-font + } + + itk_component add view_func { + combobox::combobox $itk_component(view_bottom).combo -maxheight 15 \ + -font src-font \ + -command [code $this _goto_func] + } { + # Should be able to do this, but can't cause the combobox doesn't + # fake up a MegaWidget well enough + #rename -background -textbackground textBackground Background + } + + itk_component add view_mode { + combobox::combobox $itk_component(view_bottom).mode -width 9 \ + -font src-font \ + -command [code $this mode] + } { + #rename -background -textbackground textBackground Background + } + + itk_component add view_search { + entry $itk_component(view_bottom).search -borderwidth 2 \ + -font src-font -width 10 \ + -background white + } { + rename -background -textbackground textBackground Background + } + + # Pack all the components of view_hidden into the frame: + + pack $itk_component(view_search) -side right -padx 5 -fill none \ + -expand 1 -anchor e + pack $itk_component(view_mode) -side right -padx 5 + pack $itk_component(view_func) -side left + + pack $itk_component(view_name) -side top -fill x -padx 5 -pady 3 + pack $itk_component(view_bottom) -side bottom -fill x -pady 3 -padx 5 + pack $itk_component(view_src) -fill both -expand 1 -padx 5 -pady 3 + + + # Fill combo boxes + $itk_component(view_mode) list insert end SOURCE + $itk_component(view_mode) list insert end ASSEMBLY + $itk_component(view_mode) list insert end MIXED + + # don't allow SRC+ASM mode... $itk_component(view_mode) insert end SRC+ASM + $itk_component(view_mode) entryset [$itk_component(view_src) mode_get] + + # Key bindings for hidden frame + bind_plain_key $itk_component(view_search) Return \ + [code $this _search_src forwards] + bind_plain_key $itk_component(view_search) Shift-Return \ + [code $this _search_src backwards] + + # Now map everything onto the screen + grid $itk_component(filter) -column 0 -row 0 -padx 6 -pady 4 -sticky ew + grid $itk_component(browser) -column 0 -row 1 -sticky nsew + grid $itk_component(view) -column 0 -row 2 -pady 4 -padx 6 -sticky ew + + # Now set up any initial values: + + set MoreVisible [pref get gdb/browser/view_is_open] + set BrowserHeight [pref get gdb/browser/top_height] + set Width [pref get gdb/browser/width] + + if {$BrowserHeight > 0} { + grid rowconfigure $itk_component(hull) $componentToRow(browser) \ + -minsize $BrowserHeight + } + + if {$Width > 0} { + grid columnconfigure $itk_component(hull) 0 -minsize $Width + } + + grid rowconfigure $itk_component(hull) 1 -weight 1 + grid columnconfigure $itk_component(hull) 0 -weight 1 + + update idletasks + eval $labelUpdateCode + + if {$MoreVisible} { + debug "Got moreVisible at 1" + set MoreVisible 0 + _toggle_more 1 + } + + # Fill file box + _fill_file_box + + after idle " + update idletasks + grid rowconfigure $itk_component(hull) 2 \ + -minsize \[winfo height $itk_component(view)\] + " + + # Finally set up the top level bindings: + _bind_toplevel 1 + +} + +# ------------------------------------------------------------------ +# METHOD: _filter_trace_proc +# This is called when something is entered in the filter +# box. The actual filtering is done in an after to avoid +# flashing too much if the user is typing quickly. +# ------------------------------------------------------------------ +body BrowserWin::_filter_trace_proc {v1 v2 mode} { + if {$filter_trace_after != ""} { + after cancel $filter_trace_after + } + set filter_trace_after [after 100 [code $this _filter_trace_after]] +} + +# ------------------------------------------------------------------ +# METHOD: _filter_trace_after +# This is a wrapper around search, needed to pass to trace +# ------------------------------------------------------------------ +body BrowserWin::_filter_trace_after {} { + set filter_trace_after "" + search +} + +# ------------------------------------------------------------------ +# METHOD: _search_src +# Search for text or jump to a specific line +# in source window, going in the specified DIRECTION. +# ------------------------------------------------------------------ +body BrowserWin::_search_src {direction} { + set exp [$itk_component(view_search) get] + $itk_component(view_src) search $exp $direction +} + +# ------------------------------------------------------------------ +# METHOD: search +# Search for functions matching regexp/pattern +# in specified files +# ------------------------------------------------------------------ +body BrowserWin::search {} { + + set files [$itk_component(file_box) getcurselection] + + if {[llength $files] == 0} { + return + } + + freeze_me + + set filt_pat [format $filter_regexp($cur_filter_mode) \ + [pref get gdb/search/last_symbol]] + + if {[llength $files] == [$itk_component(file_box) size]} { + set err [catch {gdb_search functions $filt_pat \ + -filename 1} matches] + } else { + set err [catch {gdb_search functions $filt_pat \ + -files $files -filename 1} matches] + } + + if {$err} { + debug "ERROR searching for [pref get gdb/search/last_symbol]: $matches" + thaw_me + return + } + + $itk_component(func_box) delete 0 end + + set i -1 + catch {unset index_to_file} + + foreach func [lsort -command "list_element_strcmp 0" $matches] { + $itk_component(func_box) insert end [lindex $func 0] + set index_to_file([incr i]) [lindex $func 1] + } + thaw_me +} + +# ------------------------------------------------------------------ +# METHOD: _toggle_more +# Toggle display of source listing +# ------------------------------------------------------------------ +body BrowserWin::_toggle_more {{in_constructor 0}} { + + debug "Running toggle_more with MoreVisible: $MoreVisible" + # Temporarily disable the resize bindings before opening the window. + _bind_toplevel 0 + + set topHeight [winfo height $Top] + set topWidth [winfo width $Top] + + if {!$MoreVisible} { + + $itk_component(view_label) configure -text {Hide Source} + $itk_component(view_more) configure -image _LESS_ + grid $itk_component(view_hidden) -row 3 -column 0 -sticky nsew \ + -padx 6 -pady 4 + + # Check the stored height. Restore the view to this if it will fit on the + # screen. Otherwise, figure out how big to make it... + + set height [pref get gdb/browser/view_height] + set bottom [expr {[winfo y $Top] + $topHeight}] + + set extra [expr {[winfo screenheight $Top] - $bottom - 20}] + + if {$height < 0} { + set default [winfo pixels $Top 3i] + set height [expr {$extra > $default ? $default : $extra}] + } else { + set height [expr {$extra > $height ? $height : $extra}] + } + + wm geometry $Top ${topWidth}x[expr {$topHeight + $height}] + grid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \ + -weight 1 + grid rowconfigure $itk_component(hull) $componentToRow(browser) -weight 0 + + pref set gdb/browser/view_height $height + + set MoreVisible 1 + update idletasks + + # If we have a selected function, display it in the window + + set f [$itk_component(func_box) getcurselection] + + if {$f != ""} { + # FIXME - If there is more than 1 function selected, I just load the + # first. It would probably be better to load the one nearest to the + # middle of the current window on the listbox. But I am running out + # of time for this round... + + if {[llength $f] > 1} { + set f [lindex $f 0] + } + + _fill_source $f + } else { + # If no function was chosen, try the file box... + + set f [$itk_component(file_box) getcurselection] + if { $f != "" } { + if {[llength $f] > 1} { + set f [lindex $f 0] + } + _fill_source $f 0 + } + } + } else { + if {!$in_constructor} { + pref set gdb/browser/view_height \ + [winfo height $itk_component(view_hidden)] + } + + $itk_component(view_label) configure -text {View Source} + $itk_component(view_more) configure -image _MORE_ + + grid propagate $itk_component(func_box) 0 + grid propagate $itk_component(file_box) 0 + + set newTopHeight [expr {$topHeight - \ + [winfo height $itk_component(view_hidden)]}] + wm geometry $Top ${topWidth}x$newTopHeight + + if {!$in_constructor} { + grid rowconfigure $itk_component(hull) $componentToRow(browser) -weight 1 + grid forget $itk_component(view_hidden) + grid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \ + -minsize 0 -weight 0 + } + + set MoreVisible 0 + + # Flush the changes + + update idletasks + + grid propagate $itk_component(func_box) 1 + grid propagate $itk_component(file_box) 1 + + } + + # restore the bindings + + _bind_toplevel 1 + +} + +# ------------------------------------------------------------------ +# METHOD: _bind_toplevel +# Setup the bindings for the toplevel. +# ------------------------------------------------------------------ +body BrowserWin::_bind_toplevel {install} { + + set bindings [bindtags $Top] + if {$install} { + bindtags $Top [linsert $bindings 0 Configure_Browser_$this] + } else { + set bindLoc [lsearch $bindings Configure_Browser_$this] + bindtags $Top [lreplace $bindings $bindLoc $bindLoc] + } +} + +# ------------------------------------------------------------------ +# METHOD: _do_resize +# Does the actual work of the resize. +# ------------------------------------------------------------------ +body BrowserWin::_do_resize {} { + + update idletasks + debug "Running _do_resize" + + set width [winfo width $itk_component(hull)] + pref set gdb/browser/width $width + grid columnconfigure $itk_component(hull) 0 -minsize $width + + if {$MoreVisible} { + set v_height [winfo height $itk_component(view_hidden)] + pref set gdb/browser/view_height $v_height + grid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \ + -minsize $v_height + grid rowconfigure $itk_component(hull) $componentToRow(browser) + } else { + set b_height [winfo height $itk_component(browser)] + pref set gdb/browser/top_height $b_height + grid rowconfigure $itk_component(hull) $componentToRow(browser) \ + -minsize $b_height + } + + eval $labelUpdateCode + pack propagate $Top 1 + + set resize_after "" + +} + +# ------------------------------------------------------------------ +# METHOD: _resize +# Resize "itk_component(view_hidden)" after all configure events +# ------------------------------------------------------------------ +body BrowserWin::_resize {} { + + pack propagate $Top 0 + + if {$MoreVisible} { + grid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \ + -minsize 0 + } else { + grid rowconfigure $itk_component(hull) 1 -minsize 0 + } + + grid columnconfigure $itk_component(hull) 0 -minsize 0 + + if {$resize_after != ""} { + after cancel $resize_after + } + set resize_after [after 100 "[code $this _do_resize]"] + +} + +# ------------------------------------------------------------------ +# METHOD: _process_file_selection +# This fills the func combo, and the more window if it +# is currently open with the hit in the File combobox. +# ------------------------------------------------------------------ +body BrowserWin::_process_file_selection {y} { + + set curIndex [$itk_component(file_box) nearest $y] + set curSelection [$itk_component(file_box) curselection] + + # We got a button-release - First make sure the click selected the item... + + if {[lsearch $curIndex $curSelection] >= 0} { + _fill_source [$itk_component(file_box) get $curIndex] 0 + } else { + # If the item was deselected, go back to the first one in the list... + # It would be better to keep a stack of the clicked items, and go to the + # last one on the stack. But in extended mode, this is tricky. FIXME + + if {[llength $curSelection] > 0} { + _fill_source [$itk_component(file_box) get [lindex $curSelection 0]] 0 + } else { + _fill_source "" + } + } + + search + +} + +# ------------------------------------------------------------------ +# METHOD: _process_func_selection +# This points the more window to the hit in the Func combobox +# if it is currently open. +# ------------------------------------------------------------------ +body BrowserWin::_process_func_selection {y} { + + set curIndex [$itk_component(func_box) nearest $y] + set curSelection [$itk_component(func_box) curselection] + + # We got a button-release - First make sure the click selected the item... + + if {[lsearch $curIndex $curSelection] >= 0} { + set funcName [$itk_component(func_box) get $curIndex] + set fileName $index_to_file($curIndex) + _fill_source $funcName 1 $fileName + } + +} + +# ------------------------------------------------------------------ +# METHOD: do_all_bp +# Toggle a bp at every selected function in FuncLB +# ------------------------------------------------------------------ +body BrowserWin::do_all_bp {onp} { + + set funcs [$itk_component(func_box) getcurselection] + freeze_me + + foreach f $funcs { + if {[catch {gdb_loc $f} linespec]} { + dbug W "Could not gdb_loc \"$f\"" + return + } + set bpnum [bp_exists $linespec] + if {$bpnum == -1 && $onp} { + + # FIXME: gdb_set_bp is the preferred method, but it requires + # a file and line number. This doesn't work very well for + # templates... + gdb_cmd "break $f" + } elseif {!$onp} { + catch {gdb_cmd "delete $bpnum"} + } + } + thaw_me +} + +# ------------------------------------------------------------------ +# METHOD: _toggle_bp +# Toggle bp at function specified by the given Y +# coordinate in the listbox +# ------------------------------------------------------------------ +body BrowserWin::_toggle_bp {y} { + + set f [$itk_component(func_box) get [$itk_component(func_box) nearest $y]] + if {$f != ""} { + if {[catch {gdb_loc $f} linespec]} { + return + } + set bpnum [bp_exists $linespec] + if {$bpnum == -1} { + # FIXME: gdb_set_bp is the preferred method, but it requires + # a file and line number. This doesn't work very well for + # templates... + gdb_cmd "break $f" + } else { + catch {gdb_cmd "delete $bpnum"} + } + } +} + +# ------------------------------------------------------------------ +# METHOD: _select +# (Un/Highlight all files in the files list +# ------------------------------------------------------------------ +body BrowserWin::_select {highlight} { + if {$highlight} { + $itk_component(file_box) selection set 0 end + } else { + $itk_component(file_box) selection clear 0 end + } + search +} + +# ------------------------------------------------------------------ +# METHOD: _set_filter_mode +# React to changes in the filter mode +# ------------------------------------------------------------------ +body BrowserWin::_set_filter_mode {w mode} { + if {[string compare $mode $cur_filter_mode] != 0} { + set cur_filter_mode $mode + pref set gdb/search/filter_mode $mode + search + } +} + +# ------------------------------------------------------------------ +# METHOD: _file_hide_h +# Run when the "Hide .h files" preference is chosen. +# ------------------------------------------------------------------ +body BrowserWin::_file_hide_h {} { + + _fill_file_box + search + +} + +# ------------------------------------------------------------------ +# METHOD: _fill_source +# Helper function to fill the srctextwin +# when needed. +# ------------------------------------------------------------------ +body BrowserWin::_fill_source {f {funcp 1} {filename ""}} { + + if {!$MoreVisible } { + return + } + + if {($funcp && [string compare $f $Current(function)]) \ + || [string compare $f $Current(filename)]} { + if {!$funcp} { + if {$filename == ""} { + set f $f:1 + } else { + set f $f:$filename + } + } + + if {[catch {gdb_loc $f} linespec]} { + return + } + + lassign $linespec foo funcname name line addr pc_addr lib + set file_changed [string compare $Current(filename) $name] + # fill srctextwin + + if {$file_changed} { + # Set the file name label: + $itk_component(view_name) configure -text $name: + freeze_me + } + + $itk_component(view_src) location BROWSE_TAG $name $funcname \ + $line $addr $pc_addr lib + + if {$file_changed} { + thaw_me + } + + set Current(function) $funcname + # fill func combo + if {$file_changed} { + set Current(filename) $name + _fill_funcs_combo $name + } + # Set current function in combo box + $itk_component(view_func) entryset $f + + } +} + +# ------------------------------------------------------------------ +# METHOD: mode +# Function called by srctextwin when the display +# mode changes +# ------------------------------------------------------------------ +body BrowserWin::mode {w {mode ""} {go 1}} { + if {$mode != ""} { + $itk_component(view_src) mode_set $mode $go + $itk_component(view_mode) entryset $mode + } +} + +# ------------------------------------------------------------------ +# METHOD: _goto_func +# Callback for the function combo box which +# sets the srctextwin looking at the given function (VAL) +# ------------------------------------------------------------------ +body BrowserWin::_goto_func {w {val ""}} { + if {$val != ""} { + set mang 0 + if {[info exists _mangled_func($val)]} { + set mang $_mangled_func($val) + } + if {$mang} { + set loc $val + } else { + set fn [lindex [::file split $Current(filename)] end] + set loc $fn:$val + } + debug "GOTO \"$loc\"" + if {![catch {gdb_loc $loc} result]} { + lassign $result foo funcname name line addr pc_addr lib + $itk_component(view_src) location BROWSE_TAG $name $funcname \ + $line $addr $pc_addr lib + } else { + dbug W "gdb_loc returned \"$result\"" + } + } +} +# ------------------------------------------------------------------ +# METHOD: _fill_file_box +# This private method fills the file listbox +# ------------------------------------------------------------------ +body BrowserWin::_fill_file_box {} { + # It would be cool if gdb_listfiles took a regexp to match, + # but it doesn't... + + $itk_component(file_box) clear + set allFiles [gdb_listfiles] + + if {[pref get gdb/browser/hide_h]} { + foreach file $allFiles { + if {[string compare [file extension $file] ".h"]} { + $itk_component(file_box) insert end $file + } + } + } else { + foreach file $allFiles { + $itk_component(file_box) insert end $file + } + } + search +} +# ------------------------------------------------------------------ +# METHOD: _fill_funcs_combo +# This private method fills the functions combo box +# with all the functions in NAME. +# ------------------------------------------------------------------ +body BrowserWin::_fill_funcs_combo {name} { + + $itk_component(view_func) list delete 0 end + if {$name != ""} { + set maxlen 10 + if {[catch {gdb_listfuncs $name} listfuncs]} { + tk_messageBox -icon error -default ok \ + -title "GDB" -type ok -modal system \ + -message "This file can not be found or does not contain\ndebugging information." + return + } + foreach f $listfuncs { + lassign $f func mang + if {$func == "global constructors keyed to main"} {continue} + set _mangled_func($func) $mang + $itk_component(view_func) list insert end $func + if {[string length $func] > $maxlen} { + set maxlen [string length $func] + } + } + $itk_component(view_func) configure -width [expr {$maxlen + 1}] + } +} diff --git a/gdb/gdbtk/library/browserwin.ith b/gdb/gdbtk/library/browserwin.ith new file mode 100644 index 00000000000..3ea41b3e106 --- /dev/null +++ b/gdb/gdbtk/library/browserwin.ith @@ -0,0 +1,84 @@ +# Browser window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +class BrowserWin { + inherit EmbeddedWin + + public { + method constructor {args} + method destructor {} + method mode {w {mode ""} {go 1}} + method search {} + method test_get {var} + method do_all_bp {onp} + + } + + private { + method _bind_toplevel {install} + method _build_win {} + method _do_resize {} + method _file_hide_h {} + method _fill_file_box {} + method _fill_funcs_combo {name} + method _fill_source {f {funcp 1} {filename ""}} + method _filter_trace_proc {v1 v2 mode} + method _filter_trace_after {} + method _goto_func {w {val ""}} + method _process_file_selection {y} + method _process_func_selection {y} + method _resize {} + method _search_src {direction} + method _select {highlight} + method _set_filter_mode {w mode} + method _toggle_bp {y} + method _toggle_more {{in_constructor 0}} + + variable cur_filter_mode + + variable MoreVisible 0; #whether viewing source + variable TopHalfHeight 0 + variable BottomHalfHeight 0 + variable CollapsedHeight 0; #height of the window when collapsed + variable Current; + variable labelUpdateCode "" + variable index_to_file + variable _mangled_func + variable resize_after "" + variable filter_trace_after "" + + common componentToRow + array set componentToRow { + filter 0 + browser 1 + view 2 + view_hidden 3 + } + + common filter_modes [list "starts with" \ + "contains" \ + "ends with" \ + "matches regexp"] + common filter_regexp + array set filter_regexp { + "starts with" ^%s + "contains" %s + "ends with" %s$ + "matches regexp" %s + } + } + + protected proc dont_remember_size {} { + return 1 + } +} diff --git a/gdb/gdbtk/library/console.itb b/gdb/gdbtk/library/console.itb new file mode 100644 index 00000000000..bc98f0a1dd6 --- /dev/null +++ b/gdb/gdbtk/library/console.itb @@ -0,0 +1,606 @@ +# Console window for GDBtk +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +body Console::constructor {args} { + global gdbtk_state + window_name "Console Window" + + debug "$args" + _build_win + eval itk_initialize $args + add_hook gdb_busy_hook [list $this busy] + add_hook gdb_idle_hook [list $this idle] + add_hook gdb_no_inferior_hook [list $this idle] + set gdbtk_state(console) $this +} + +body Console::destructor {} { + global gdbtk_state + set gdbtk_state(console) "" + remove_hook gdb_busy_hook [list $this busy] + remove_hook gdb_idle_hook [list $this idle] + remove_hook gdb_no_inferior_hook [list $this idle] +} + +body Console::_build_win {} { + iwidgets::scrolledtext $itk_interior.stext -hscrollmode dynamic \ + -vscrollmode dynamic -textbackground white + + set _twin [$itk_interior.stext component text] + + if {[pref get gdb/console/wrap]} { + $_twin configure -wrap word + } else { + $_twin configure -wrap none + } + + $_twin tag configure prompt_tag -foreground [pref get gdb/console/prompt_fg] + $_twin tag configure err_tag -foreground [pref get gdb/console/error_fg] + $_twin configure -font [pref get gdb/console/font] + + # + # bind editing keys for console window + # + bind $_twin <Return> "$this invoke; break" + + # disable this + bind_plain_key $_twin Control-o "break" + + # History control. + bind_plain_key $_twin Control-p "[code $this _previous]; break" + bind $_twin <Up> "[code $this _previous]; break" + bind_plain_key $_twin Control-n "[code $this _next]; break" + bind $_twin <Down> "[code $this _next]; break" + bind $_twin <Meta-less> "[code $this _first]; break" + bind $_twin <Home> "[code $this _first]; break" + bind $_twin <Meta-greater> "[code $this _last]; break" + bind $_twin <End> "[code $this _last]; break" + + # Tab completion + bind_plain_key $_twin KeyPress-Tab "[code $this _complete]; break" + + # Don't let left arrow or ^B go over the prompt + bind_plain_key $_twin Control-b { + if {[%W compare insert <= {cmdmark + 1 char}]} { + break + } + } + bind $_twin <Left> [bind $_twin <Control-b>] + + # Don't let Control-h, Delete, or Backspace back up over the prompt. + bind_plain_key $_twin Control-h "[code $this _delete]; break" + + bind $_twin <BackSpace> "[code $this _delete]; break" + + bind $_twin <Delete> "[code $this _delete 1]; break" + + # Control-a moves to start of line. + bind_plain_key $_twin Control-a { + %W mark set insert {cmdmark + 1 char} + break + } + + # Control-u deletes to start of line. + bind_plain_key $_twin Control-u { + %W delete {cmdmark + 1 char} insert + } + + # Control-w deletes previous word. + bind_plain_key $_twin Control-w { + if {[%W compare {insert -1c wordstart} > cmdmark]} { + %W delete {insert -1c wordstart} insert + } + } + + bind $_twin <Control-Up> "[code $this _search_history]; break" + bind $_twin <Shift-Up> "[code $this _search_history]; break" + bind $_twin <Control-Down> "[code $this _rsearch_history]; break" + bind $_twin <Shift-Down> "[code $this _rsearch_history]; break" + + # Don't allow key motion to move insertion point outside the command + # area. This is done by fixing up the insertion point after any key + # movement. We only need to do this after events we do not + # explicitly override. Note that since the edit line is always the + # last line, we can't possibly go past it, so we don't bother + # checking that. + foreach event [bind Text] { + if {[string match *Key* $event] && [bind $_twin $event] == ""} { + bind $_twin $event { + if {[%W compare insert <= {cmdmark + 1 char}]} { + %W mark set insert {cmdmark + 1 char} + } + } + } + } + + # Don't allow mouse to put cursor outside command line. For some + # events we do this by noticing when the cursor is outside the + # range, and then saving the insertion point. For others we notice + # the saved insertion point. + set pretag pre-$_twin + bind $_twin <1> [format { + if {[%%W compare [tkTextClosestGap %%W %%x %%y] <= cmdmark]} { + %s _insertion [%%W index insert] + } else { + %s _insertion {} + } + } $this $this] + bind $_twin <B1-Motion> [format { + if {[%s _insertion] != ""} { + %%W mark set insert [%s _insertion] + } + } $this $this $this] + # FIXME: has inside information. + bind $_twin <ButtonRelease-1> [format { + tkCancelRepeat + if {[%s _insertion] != ""} { + %%W mark set insert [%s _insertion] + } + %s _insertion {} + break + } $this $this $this] + + # Don't allow inserting text outside the command line. FIXME: + # requires inside information. + # Also make it a little easier to paste by making the button + # drags a little "fuzzy". + bind $_twin <B2-Motion> { + if {!$tk_strictMotif} { + if {($tkPriv(x) - 2 < %x < $tkPriv(x) + 2) \ + || ($tkPriv(y) - 2 < %y < $tkPriv(y) + 2)} { + set tkPriv(mouseMoved) 1 + } + if {$tkPriv(mouseMoved)} { + %W scan dragto %x %y + } + } + break + } + bind $_twin <ButtonRelease-2> [format { + if {!$tkPriv(mouseMoved) || $tk_strictMotif} { + %s + break + } + } [code $this _paste 1]] + bind $_twin <<Paste>> "[code $this _paste 0]; break" + bind $_twin <<PasteSelection>> "[code $this _paste 0]; break" + + _setprompt + pack $itk_interior.stext -expand yes -fill both + + focus $_twin + +} + +body Console::idle {} { + set _running 0 +} + +body Console::busy {} { + set _running 1 +} + +# ------------------------------------------------------------------ +# METHOD: insert - insert new text in the text widget +# ------------------------------------------------------------------ +body Console::insert {line} { + if {$_needNL} { + $_twin insert {insert linestart} "\n" + } + # Remove all \r characters from line. + set line [join [split $line \r] {}] + $_twin insert {insert -1 line lineend} $line + + set nlines [lindex [split [$_twin index end] .] 0] + if {$nlines > $throttle} { + set delta [expr {$nlines - $throttle}] + $_twin delete 1.0 ${delta}.0 + } + + $_twin see insert + set _needNL 0 + ::update idletasks +} + +#------------------------------------------------------------------- +# METHOD: einsert - insert error text in the text widget +# ------------------------------------------------------------------ +body Console::einsert {line} { + debug $line + if {$_needNL} { + $_twin insert end "\n" + } + $_twin insert end $line err_tag + $_twin see insert + set _needNL 0 +} + +#------------------------------------------------------------------- +# METHOD: _previous - recall the previous command +# ------------------------------------------------------------------ +body Console::_previous {} { + if {$_histElement == -1} { + # Save partial command. + set _partialCommand [$_twin get {cmdmark + 1 char} {cmdmark lineend}] + } + incr _histElement + set text [lindex $_history $_histElement] + if {$text == ""} { + # No dice. + incr _histElement -1 + # FIXME flash window. + } else { + $_twin delete {cmdmark + 1 char} {cmdmark lineend} + $_twin insert {cmdmark + 1 char} $text + } +} + +#------------------------------------------------------------------- +# METHOD: _search_history - search history for match +# ------------------------------------------------------------------ +body Console::_search_history {} { + set str [$_twin get {cmdmark + 1 char} {cmdmark lineend}] + + if {$_histElement == -1} { + # Save partial command. + set _partialCommand $str + set ix [lsearch $_history ${str}*] + } else { + set str $_partialCommand + set num [expr $_histElement + 1] + set ix [lsearch [lrange $_history $num end] ${str}*] + incr ix $num + } + + set text [lindex $_history $ix] + if {$text != ""} { + set _histElement $ix + $_twin delete {cmdmark + 1 char} {cmdmark lineend} + $_twin insert {cmdmark + 1 char} $text + } +} + +#------------------------------------------------------------------- +# METHOD: _rsearch_history - search history in reverse for match +# ------------------------------------------------------------------ +body Console::_rsearch_history {} { + if {$_histElement != -1} { + set str $_partialCommand + set num [expr $_histElement - 1] + set ix $num + while {$ix >= 0} { + if {[string match ${str}* [lindex $_history $ix]]} { + break + } + incr ix -1 + } + + set text "" + if {$ix >= 0} { + set text [lindex $_history $ix] + set _histElement $ix + } else { + set text $_partialCommand + set _histElement -1 + } + $_twin delete {cmdmark + 1 char} {cmdmark lineend} + $_twin insert {cmdmark + 1 char} $text + } +} + +#------------------------------------------------------------------- +# METHOD: _next - recall the next command (scroll forward) +# ------------------------------------------------------------------ +body Console::_next {} { + if {$_histElement == -1} { + # FIXME flash window. + return + } + incr _histElement -1 + if {$_histElement == -1} { + set text $_partialCommand + } else { + set text [lindex $_history $_histElement] + } + $_twin delete {cmdmark + 1 char} {cmdmark lineend} + $_twin insert {cmdmark + 1 char} $text +} + +#------------------------------------------------------------------- +# METHOD: _last - get the last history element +# ------------------------------------------------------------------ +body Console::_last {} { + set _histElement 0 + _next +} + +#------------------------------------------------------------------- +# METHOD: _first - get the first (earliest) history element +# ------------------------------------------------------------------ +body Console::_first {} { + set _histElement [expr {[llength $_history] - 1}] + _previous +} + + + +#------------------------------------------------------------------- +# METHOD: _setprompt - put a prompt at the beginning of a line +# ------------------------------------------------------------------ +body Console::_setprompt {{prompt {}}} { + if {$_invoking} { + set prompt "" + } elseif {"$prompt" != ""} { + # nothing + } else { + #set prompt [pref get gdb/console/prompt] + set prompt [gdb_prompt] + } + + $_twin insert {insert linestart} $prompt prompt_tag + $_twin mark set cmdmark "insert -1 char" + $_twin see insert +} + +#------------------------------------------------------------------- +# METHOD: activate - run this after a command is run +# ------------------------------------------------------------------ +body Console::activate {{prompt {}}} { + if {$_invoking > 0} { + incr _invoking -1 + _setprompt $prompt + } +} + +#------------------------------------------------------------------- +# METHOD: invoke - invoke a command +# ------------------------------------------------------------------ +body Console::invoke {} { + global gdbtk_state + + incr _invoking + set text [$_twin get {cmdmark + 1 char} {cmdmark lineend}] + if {$text == ""} { + set text [lindex $_history 0] + $_twin insert {insert lineend} $text + } + $_twin mark set insert {insert lineend} + $_twin insert {insert lineend} "\n" + + set ok 0 + if {$_running} { + if {[string index $text 0] == "!"} { + set text [string range $text 1 end] + set ok 1 + } + } + + # Only push new nonempty history items. + if {$text != "" && [lindex $_history 0] != $text} { + lvarpush _history $text + } + + set index [$_twin index insert] + + # Clear current history element, and current partial element. + set _histElement -1 + set _partialCommand "" + + # Need a newline before next insert. + set _needNL 1 + + # run command + if {$gdbtk_state(readline)} { + set gdbtk_state(readline_response) $text + return + } + + if {!$_running || $ok} { + set result [catch {gdb_immediate "$text" 1} message] + } else { + set result 1 + set message "The debugger is busy." + } + + # gdb_immediate may take a while to finish. Exit if + # our window has gone away. + if {![winfo exists $_twin]} { return } + + if {$result} { + global errorInfo + dbug W "Error: $errorInfo\n" + $_twin insert end "Error: $message\n" err_tag + } elseif {$message != ""} { + $_twin insert $index "$message\n" + } + + # Make the prompt visible again. + activate + + # Make sure the insertion point is visible. + $_twin see insert +} + +#------------------------------------------------------------------- +# PRIVATE METHOD: _delete - Handle a Delete of some sort. +# ------------------------------------------------------------------ +body Console::_delete {{right 0}} { + + # If we are deleting to the right, and we have this turned off, + # delete to the right. + + if {$right && ![pref get gdb/console/deleteLeft]} { + set right 0 + } + + if {!$right} { + set insert_valid [$_twin compare insert > {cmdmark + 1 char}] + set delete_loc "insert-1c" + } else { + set insert_valid [$_twin compare insert > cmdmark] + set delete_loc "insert" + } + + # If there is a selection on the command line, delete it, + # If there is a selection above the command line, do a + # regular delete, but don't delete the prompt. + # If there is no selection, do the delete. + + if {![catch {$_twin index sel.first}]} { + if {[$_twin compare sel.first <= cmdmark]} { + if {$insert_valid} { + $_twin delete $delete_loc + } + } else { + $_twin delete sel.first sel.last + } + } elseif {$insert_valid} { + $_twin delete $delete_loc + } +} + +#------------------------------------------------------------------- +# PRIVATE METHOD: _insertion - Set or get saved insertion point +# ------------------------------------------------------------------ +body Console::_insertion {args} { + if {! [llength $args]} { + return $_saved_insertion + } else { + set _saved_insertion [lindex $args 0] + } +} + +# ------------------------------------------------------------------ +# METHOD: _paste - paste the selection into the console window +# ------------------------------------------------------------------ +body Console::_paste {{check_primary 1}} { + set sel {} + + if {!$check_primary || [catch {selection get} sel] || $sel == ""} { + if {[catch {selection get -selection CLIPBOARD} sel] || $sel == ""} { + return + } + } + + #if there is a selection, insert over it: + if {![catch {$_twin index sel.first}] + && [$_twin compare sel.first > {cmdmark + 1 char}]} { + set point [$_twin index sel.first] + $_twin delete sel.first sel.last + $_twin insert $point $sel + } else { + $_twin insert insert $sel + } +} + +# public method for testing only +body Console::get_text {} { + return $_twin +} + +# ------------------------------------------------------------------ +# METHOD: _find_lcp - Return the longest common prefix in SLIST. +# Can be empty string. +# ------------------------------------------------------------------ +body Console::_find_lcp {slist} { + # Handle trivial cases where list is empty or length 1 + if {[llength $slist] <= 1} {return [lindex $slist 0]} + + set prefix [lindex $slist 0] + set prefixlast [expr [string length $prefix] - 1] + + foreach str [lrange $slist 1 end] { + set test_str [string range $str 0 $prefixlast] + while {[string compare $test_str $prefix] != 0} { + incr prefixlast -1 + set prefix [string range $prefix 0 $prefixlast] + set test_str [string range $str 0 $prefixlast] + } + if {$prefixlast < 0} break + } + return $prefix +} + +# ------------------------------------------------------------------ +# METHOD: _find_completion - Look through COMPLETIONS to generate +# the suffix needed to do command +# ------------------------------------------------------------------ +body Console::_find_completion {cmd completions} { + # Get longest common prefix + set lcp [_find_lcp $completions] + set cmd_len [string length $cmd] + # Return suffix beyond end of cmd + return [string range $lcp $cmd_len end] +} + +# ------------------------------------------------------------------ +# METHOD: _complete - Command line completion +# ------------------------------------------------------------------ +body Console::_complete {} { + + set command_line [$_twin get {cmdmark + 1 char} {cmdmark lineend}] + set choices [gdb_cmd "complete $command_line" 1] + set choices [string trimright $choices \n] + set choices [split $choices \n] + + # Just do completion if this is the first tab + if {!$_saw_tab} { + set _saw_tab 1 + set completion [_find_completion $command_line $choices] + + # Here is where the completion is actually done. If there + # is one match, complete the command and print a space. + # If two or more matches, complete the command and beep. + # If no match, just beep. + switch {[llength $choices]} { + 0 {} + 1 { + _twin insert end "$completion " + set _saw_tab 0 + return + } + + default { + $_twin insert end $completion + } + } + bell + $_twin see end + bind $_twin <KeyPress> [code $this _reset_tab] + } else { + # User hit another consecutive tab. List the choices. + # Note that at this point, choices may contain commands + # with spaces. We have to lop off everything before (and + # including) the last space so that the completion list + # only shows the possibilities for the last token. + set choices [lsort $choices] + if {[regexp ".* " $command_line prefix]} { + regsub -all $prefix $choices {} choices + } + if {[llength choices] != 0} { + insert "\nCompletions:\n[join $choices \ ]\n" + $_twin see end + bind $_twin <KeyPress> [code $this _reset_tab] + } + } +} + +# ------------------------------------------------------------------ +# METHOD: _reset_tab - Helper method for tab completion. Used +# to reset the tab when a key is pressed. +# ------------------------------------------------------------------ +body Console::_reset_tab {} { + bind $_twin <KeyPress> {} + set _saw_tab 0 +} diff --git a/gdb/gdbtk/library/console.ith b/gdb/gdbtk/library/console.ith new file mode 100644 index 00000000000..047991368c7 --- /dev/null +++ b/gdb/gdbtk/library/console.ith @@ -0,0 +1,65 @@ +# Console window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements a console display widget using primitive widgets as the building +# blocks. +# ---------------------------------------------------------------------- + +class Console { + inherit EmbeddedWin + + public { + #Approximate maximum number of lines allowed in widget + variable throttle 2000 + + method constructor {args} + method destructor {} + method idle {} + method busy {} + method insert {line} + method einsert {line} + method invoke {} + method _insertion {args} + method get_text {} + method activate {{prompt {}}} + } + + private { + variable _twin + variable _invoking 0 + variable _needNL 1 + variable _history {} + variable _histElement -1 + variable _partialCommand "" + variable _saved_insertion "" + variable _running 0 + variable _saw_tab 0 + + method _build_win {} + method _complete {} + method _delete {{left 0}} + method _find_completion {cmd completions} + method _find_lcp {slist} + method _first {} + method _last {} + method _next {} + method _paste {{check_primary 1}} + method _previous {} + method _reset_tab {} + method _search_history {} + method _rsearch_history {} + method _setprompt {{prompt {}}} + } +} diff --git a/gdb/gdbtk/library/data.itb b/gdb/gdbtk/library/data.itb new file mode 100644 index 00000000000..ba756753824 --- /dev/null +++ b/gdb/gdbtk/library/data.itb @@ -0,0 +1,48 @@ +# Data-type class implementations for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# ------------------------------------------------------------------ +# Stack +# ------------------------------------------------------------------ +body Stack::constructor {} { + set _stack {} +} + +body Stack::push {args} { + set _stack [concat $_stack $args] +} + +body Stack::destructor {} { +} + +body Stack::pop {} { + set thing [lindex $_stack end] + set _stack [lreplace $_stack end end] + return $thing +} + +# ------------------------------------------------------------------ +# Queue +# ------------------------------------------------------------------ +body Queue::constructor {} { +} + +body Queue::destructor {} { +} + +body Queue::pop {} { + set thing [lindex $_stack 0] + set _stack [lreplace $_stack 0 0] + return $thing +} + diff --git a/gdb/gdbtk/library/data.ith b/gdb/gdbtk/library/data.ith new file mode 100644 index 00000000000..cf2e2c51e42 --- /dev/null +++ b/gdb/gdbtk/library/data.ith @@ -0,0 +1,42 @@ +# Data-type class definitions for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# Generic Stack +class Stack { + + public { + method constructor {} + method destructor {} + + # Pop the stack. Empty string means empty stack. + method pop {} + + # Push ARGS onto the stack. + method push {args} + } + + protected variable _stack +} + +# Generic Queue +class Queue { + inherit Stack + + public { + method constructor {} + method destructor {} + + # Pop the queue. Empty string means empty queue. + method pop {} + } +} diff --git a/gdb/gdbtk/library/debugwin.itb b/gdb/gdbtk/library/debugwin.itb new file mode 100644 index 00000000000..7ba9b7d0bea --- /dev/null +++ b/gdb/gdbtk/library/debugwin.itb @@ -0,0 +1,409 @@ +# Debug window for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::constructor +# +# SYNOPSIS: constructor::args +# +# DESC: Creates the debug window +# +# ARGS: None are used yet. +# ----------------------------------------------------------------------------- +body DebugWin::constructor {args} { + debug "" + window_name "GDBTK Debug" "Debug" + + build_win + incr numTopWins +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::destructor +# +# SYNOPSIS: Not called by hand +# +# DESC: Destroys the debug window +# +# ARGS: None +# ----------------------------------------------------------------------------- +body DebugWin::destructor {} { + # notify debug code that window is going away + ::debug::debugwin "" + incr numTopWins -1 +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::build_win +# +# SYNOPSIS: build_win +# +# DESC: Creates the Debug Window. Reads the contents of the debug log +# file, if it exists. Notifies the debug functions in ::debug +# to send output here. +# ----------------------------------------------------------------------------- +body DebugWin::build_win {} { + global gdb_ImageDir GDBTK_LIBRARY + + set top [winfo toplevel $itk_interior] + + # initialize the gdbtk_de array + if {![info exists ::gdbtk_de]} { + set ::gdbtk_de(ALL) 1 + set ::gdbtk_de(others) 0 + } + + # create menubar + set menu [menu $itk_interior.m -tearoff 0] + $menu add cascade -menu $menu.file -label "File" -underline 0 + set m [menu $menu.file] + $m add command -label "Clear" -underline 1 \ + -command [code $this _clear] + $m add command -label "Mark Old" -underline 1 \ + -command [code $this _mark_old] + $m add separator + $m add command -label "Save" -underline 0 \ + -command [code $this _save_contents] + $m add separator + $m add command -label "Close" -underline 0 \ + -command "::debug::debugwin {};delete object $this" + $menu add cascade -menu $menu.trace -label "Trace" + set m [menu $menu.trace] + $m add radiobutton -label Start -variable ::debug::tracing -value 1 + $m add radiobutton -label Stop -variable ::debug::tracing -value 0 + $menu add cascade -menu $menu.rs -label "ReSource" + set m [menu $menu.rs] + foreach f [lsort [glob [file join $GDBTK_LIBRARY *.itb]]] { + $m add command -label "Source [file tail $f]"\ + -command [list source $f] + } + $m add separator + $m add command -label "Source ALL" -command [code $this _source_all] + + $menu add cascade -menu $menu.opt -label "Options" + set m [menu $menu.opt] + $m add command -label "Display" -underline 0 \ + -command [list ManagedWin::open DebugWinDOpts -over $this] + if {!$::debug::initialized} { + $menu entryconfigure 1 -state disabled + $menu add cascade -label " Tracing Not Initialized" -foreground red \ + -activeforeground red + } + $menu add cascade -menu $menu.help -label "Help" -underline 0 + set m [menu $menu.help] + $m add command -label "Debugging Functions" -underline 0 \ + -command {ManagedWin::open HtmlViewer -force -file debug.html \ + -topics {{{"Debug Functions" debug.html}}}} + + $top configure -menu $menu + + iwidgets::scrolledtext $itk_interior.s -hscrollmode static \ + -vscrollmode static -wrap none -textbackground black -foreground white + set _t [$itk_interior.s component text] + pack $itk_interior.s -expand 1 -fill both + + # define tags + foreach color $_colors { + $_t tag configure [lindex $color 0] -foreground [lindex $color 1] + } + $_t tag configure trace -foreground gray + $_t tag configure args -foreground blue + $_t tag configure marked -background grey20 + + loadlog + + # now notify the debug functions to use this window + ::debug::debugwin $this + + # override the window delete procedure so the messages are + # turned off first. + wm protocol $top WM_DELETE_WINDOW "::debug::debugwin {};destroy $top" + +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::puts +# +# SYNOPSIS: puts {level cls func msg} +# +# DESC: Writes debugging information into the DebugWin. A filter +# will be applied to determine if the message should be +# displayed or not. +# +# ARGS: level - priority level. See debug::dbug for details. +# cls - class name of caller, for example "SrcWin" +# func - function name of caller +# msg - message to display +# ----------------------------------------------------------------------------- +body DebugWin::puts {level cls func msg} { + + # filter. check if we should display this message + # for now we always let high-level messages through + if {!$::gdbtk_de(ALL) && $level == "I"} { + if {[info exists ::gdbtk_de($cls)]} { + if {!$::gdbtk_de($cls)} { + return + } + } elseif {!$::gdbtk_de(others)} { + return + } + } + + if {$func != ""} { + append cls ::$func + } + $_t insert end "($cls) " {} "$msg\n" $level + $_t see insert +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::put_trace +# +# SYNOPSIS: put_trace {enter level func ar} +# +# DESC: Writes trace information into the DebugWin. A filter +# will be applied to determine if the message should be +# displayed or not. +# +# ARGS: enter - 1 if this is a function entry, 0 otherwise. +# level - stack level +# func - function name +# ar - function arguments +# ----------------------------------------------------------------------------- +body DebugWin::put_trace {enter level func ar} { + set x [expr {$level * 2 - 2}] + if {$enter} { + $_t insert end "[string range $_bigstr 0 $x]$func " trace "$ar\n" args + } else { + $_t insert end "[string range $_bigstr 0 $x]<- $func " trace "$ar\n" args + } + $_t see insert +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::loadlog +# +# SYNOPSIS: loadlog +# +# DESC: Reads the contents of the debug log file, if it exists, into +# the DebugWin. +# ----------------------------------------------------------------------------- +body DebugWin::loadlog {} { + $_t delete 0.0 end + # Now load in log file, if possible. + # this is rather rude, using the logfile variable in the debug namespace + if {$::debug::logfile != "" && $::debug::logfile != "stdout"} { + flush $::debug::logfile + seek $::debug::logfile 0 start + while {[gets $::debug::logfile line] >= 0} { + while {[catch {set f [lindex $line 0]} f]} { + # If the lindex failed its because the remainder of the + # list is on the next line. Get it. + if {[gets $::debug::logfile line2] < 0} { + break + } + append line \n $line2 + } + if {$f == "T"} { + put_trace [lindex $line 1] [lindex $line 2] [lindex $line 3] \ + [lindex $line 4] + } else { + puts $f [lindex $line 1] [lindex $line 2] [lindex $line 3] + } + } + } +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::_source_all +# +# SYNOPSIS: _source_all +# +# DESC: Re-sources all the .itb files. +# ----------------------------------------------------------------------------- +body DebugWin::_source_all {} { + foreach f [glob [file join $::GDBTK_LIBRARY *.itb]] { + source $f + } +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::_clear +# +# SYNOPSIS: _clear +# +# DESC: Clears out the content of the debug window. +# ----------------------------------------------------------------------------- +body DebugWin::_clear {} { + $_t delete 1.0 end +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::_mark_old +# +# SYNOPSIS: _mark_old +# +# DESC: Changes the background of the current contents of the window. +# ----------------------------------------------------------------------------- +body DebugWin::_mark_old {} { + $_t tag add marked 1.0 "end - 1c" +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWin::_save_contents +# +# SYNOPSIS: _save_contents +# +# DESC: Changes the background of the current contents of the window. +# ----------------------------------------------------------------------------- +body DebugWin::_save_contents {} { + set file [tk_getSaveFile -title "Choose debug window dump file" \ + -parent [winfo toplevel $itk_interior]] + if {$file == ""} { + return + } + + if {[catch {::open $file w} fileH]} { + tk_messageBox -type ok -icon error -message \ + "Can't open file: \"$file\". \n\nThe error was:\n\n\"$fileH\"" + return + } + ::puts $fileH [$_t get 1.0 end] + +} + +############################################################################### +# ----------------------------------------------------------------------------- +# NAME: DebugWinDOpts::constructor +# +# SYNOPSIS: constructor +# +# DESC: Creates the Debug Window Options Dialog. +# ----------------------------------------------------------------------------- +body DebugWinDOpts::constructor {args} { + window_name "Debug Window Options" + build_win + eval itk_initialize $args +} + +############################################################################### +# ----------------------------------------------------------------------------- +# NAME: DebugWinDOpts::destructor +# +# SYNOPSIS: Not called by hand +# +# DESC: Destroys the Debug Window Options Dialog. +# ----------------------------------------------------------------------------- +body DebugWinDOpts::destructor {} { +} + + +# ----------------------------------------------------------------------------- +# NAME: DebugWinDOpts::build_win +# +# SYNOPSIS: build_win +# +# DESC: Creates the Debug Window Options Dialog. This dialog allows the +# user to select which information is displayed in the debug +# window and (eventually) how it looks. +# ----------------------------------------------------------------------------- +body DebugWinDOpts::build_win {} { + wm title [winfo toplevel $itk_interior] "Debug Display Options" + # initialize here so we can resource this file and update the list + set _classes {DebugWin RegWin SrcBar SrcWin ToolBar WatchWin EmbeddedWin \ + ManagedWin GDBWin StackWin SrcTextWin VariableWin global BPWin \ + TargetSelection ModalDialog ProcessWin} + set f [frame $itk_interior.f] + set btns [frame $itk_interior.buttons] + + iwidgets::Labeledframe $f.classes -labelpos nw -labeltext {Classes} + set fr [$f.classes childsite] + + checkbutton $fr.0 -text ALL -variable ::gdbtk_de(ALL) -command [code $this _all] + set i 1 + foreach cls [lsort $_classes] { + if {![info exists ::gdbtk_de($cls)]} { + set ::gdbtk_de($cls) 0 + } + checkbutton $fr.$i -text $cls -variable ::gdbtk_de($cls) + incr i + } + checkbutton $fr.$i -text others -variable ::gdbtk_de(others) + incr i + + set k [expr 3*(int($i/3))] + set more [expr $i - $k] + set j 0 + while {$j < $k} { + grid $fr.$j $fr.[expr $j+1] $fr.[expr $j+2] -sticky w -padx 5 -pady 5 + incr j 3 + } + switch $more { + 1 { grid $fr.$j x x -sticky w -padx 5 -pady 5} + 2 { grid $fr.$j $fr.[expr $j+1] x -sticky w -padx 5 -pady 5} + } + + pack $f.classes -side top -expand 1 -fill both + + button $btns.ok -text [gettext OK] -width 7 -command [code delete object $this] \ + -default active + button $btns.apply -text "Apply to All" -width 7 \ + -command [code $this _apply] + if {$::debug::logfile == "" || $::debug::logfile == "stdout"} { + $btns.apply configure -state disabled + } + button $btns.help -text [gettext Help] -width 10 -command [code $this help] \ + -state disabled + standard_button_box $btns + bind $btns.ok <Return> "$btns.ok flash; $btns.ok invoke" + bind $btns.apply <Return> "$btns.apply flash; $btns.apply invoke" + bind $btns.help <Return> "$btns.help flash; $btns.help invoke" + + pack $btns $f -side bottom -expand 1 -fill both -anchor e + focus $btns.ok +} + +# ----------------------------------------------------------------------------- +# NAME: DebugWinDOpts::_all +# +# SYNOPSIS: _all +# +# DESC: Callback for selecting ALL classes. If the user selects ALL, +# deselect all the individual class checkbuttons. +# ----------------------------------------------------------------------------- +body DebugWinDOpts::_all {} { + if {$::gdbtk_de(ALL)} { + foreach cls $_classes { + set ::gdbtk_de($cls) 0 + } + set ::gdbtk_de(others) 0 + } +} + + +# ----------------------------------------------------------------------------- +# NAME: DebugWinDOpts::_apply +# +# SYNOPSIS: _apply +# +# DESC: Callback for the "Apply" button. Loads the contents of the +# log file through the new filter into the debug window. The +# button is disabled if there is no log file. +# ----------------------------------------------------------------------------- +body DebugWinDOpts::_apply {} { + set dw [ManagedWin::find DebugWin] + if {$dw != ""} { + $dw loadlog + } +} diff --git a/gdb/gdbtk/library/debugwin.ith b/gdb/gdbtk/library/debugwin.ith new file mode 100644 index 00000000000..c9734c232e5 --- /dev/null +++ b/gdb/gdbtk/library/debugwin.ith @@ -0,0 +1,85 @@ +# Debug window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ----------------------------------------------------------------------------- +# NAME: +# class DebugWin +# +# DESC: +# This class implements a debug output window to display internal +# debugging information. It can handle debugging messages, tracing, +# and eventually profiling. +# +# NOTES: +# This window is for developers. +# +# ----------------------------------------------------------------------------- +class DebugWin { + inherit ManagedWin + + private { + variable _t + variable _colors { + {I green} + {W yellow} + {E orange} + {X red} + } + variable _bigstr " " + method build_win {} + method _source_all {} + method _clear {} + method _mark_old {} + method _save_contents {} + } + + public { + method constructor {args} + method destructor {} + method puts {level cls func msg} + method put_trace {enter level func ar} + method loadlog {} + } +} + +# ----------------------------------------------------------------------------- +# NAME: +# class DebugWinDOpts +# +# DESC: +# This class implements a debug options dialog for the DebugWin. +# Currently this consists os a selection dialog to choose which +# messages to print. Eventually it could also include a filter +# for different priorities and color selections. +# +# NOTES: +# This window is for developers. +# +# ----------------------------------------------------------------------------- +class DebugWinDOpts { + inherit ManagedWin + + public { + method constructor {args} {} + method destructor {} + } + + private { + variable _classes + method build_win {} + method _all {} + method _apply {} + } + +} diff --git a/gdb/gdbtk/library/download.itb b/gdb/gdbtk/library/download.itb new file mode 100644 index 00000000000..c4de6d4723e --- /dev/null +++ b/gdb/gdbtk/library/download.itb @@ -0,0 +1,277 @@ +# Download class implementation for GDBtk. +# Copyright 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Download window and associated procs +# +# ---------------------------------------------------------------------- + +body Download::constructor {args} { + global gdb_pretty_name + debug $args + eval itk_initialize $args + window_name "Download Status" "Download" + add_hook download_progress_hook "$this update_download" + + label $itk_interior.dload -text "Downloading $filename to $gdb_pretty_name" + + label $itk_interior.stat + set f [frame $itk_interior.f] + + set i 0 + while {$i <$num_sections} { + tixMeter $f.meter$i -value 0 -text 0 + label $f.sec$i -text [lindex $section(names) $i] -anchor w + label $f.num$i -text $bytes($i) -anchor e + grid $f.sec$i $f.meter$i $f.num$i -padx 4 -pady 4 -sticky news + incr i + } + + grid $itk_interior.dload -padx 5 -pady 5 + grid $itk_interior.stat -padx 5 -pady 5 + grid $itk_interior.f -padx 5 -pady 5 + + button $itk_interior.cancel -text Cancel -command "$this cancel" \ + -state active -width 10 + grid $itk_interior.cancel -padx 5 -pady 5 +# grid $itk_interior + +} + +# ------------------------------------------------------------------ +# METHOD: update_download - update the download meters +# ------------------------------------------------------------------ +body Download::update_download { sec num tot } { + + # Loop through all the sections, marking each as either done or + # updating its meter. This will mark all previous sections prior to + # SEC as complete. + foreach s $section(names) { + set i $section($s) + + if {$s == $sec} { + $itk_interior.f.meter$i config -value [expr {$num / $bytes($i)}] -text $num + break + } else { + if {[expr {double([$itk_interior.f.meter$i cget -value])}] != 1.0} { + $itk_interior.f.meter$i config -value 1.0 -text [expr {int($bytes($i))}] + } + } + } + ::update +} + +# ------------------------------------------------------------------ +# METHOD: done - notification that the download is really complete +# ------------------------------------------------------------------ +body Download::done { {msg ""} } { + bell + + if {$msg == ""} { + # download finished + set secs [expr {[clock seconds] - $::download_start_time}] + if {$secs == 0} { incr secs } + $itk_interior.cancel config -state disabled + set bps [expr {8 * $total_bytes / $secs / 1000}] + $itk_interior.stat config -text "$total_bytes bytes in $secs seconds ($bps kbps)" + + # set all indicators to FULL + foreach sec $section(names) { + set i $section($sec) + $itk_interior.f.meter$i config -value 1.0 -text "DONE" + } + } else { + # download failed + if {$msg != "CANCEL"} { + $itk_interior.stat config -text $msg + } + } + + # enable OK button + $itk_interior.cancel config -state active -text OK -command "delete object $this" + ::update +} + +# ------------------------------------------------------------------ +# METHOD: cancel - cancel the download +# ------------------------------------------------------------------ +body Download::cancel {} { + debug "canceling the download" + set ::download_cancel_ok 1 +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body Download::destructor {} { + remove_hook download_progress_hook "$this update_download" +} + +body Download::do_download_hooks {} { + set ::download_timer(ok) 1 +} + +body Download::download_hash { section num } { + global download_timer + debug "sec=$section num=$num tot=$total_bytes ok=$::download_cancel_ok" + ::update + # Only run the timer at discrete times... + if {[info exists download_timer(timer)]} { + after cancel $download_timer(timer) + } + + set download_timer(timer) [after 333 Download::do_download_hooks] + if {![info exists download_timer(ok)] || $download_timer(ok)} { + run_hooks download_progress_hook $section $num $total_bytes + ::update + unset download_timer(timer) + set download_timer(ok) 0 + } + + return $::download_cancel_ok +} + +# Download the executable. Return zero for success, and non-zero for error. +body Download::download_it { } { + global gdb_exe_name gdb_downloading gdb_loaded + global gdb_target_name gdb_pretty_name + global gdb_running + + debug "exe=$gdb_exe_name downloading=$gdb_downloading" + debug " loaded=$gdb_loaded target=$gdb_target_name running=$gdb_running" + + if {$gdb_downloading || $gdb_exe_name == ""} { + return 0 + } + + set gdb_downloading 1 + set gdb_loaded 0 + # Make sure the source window has had time to be created + ::update + + gdbtk_busy + + # Only places that load files should do set_exe + #set_exe + switch [set_target] { + ERROR { + # target command failed + set gdb_downloading 0 + gdbtk_idle + return 0 + } + CANCELED { + # command cancelled by user + set gdb_downloading 0 + if {$gdb_running} { + # Run the idle hooks (free the UI) + gdbtk_update + gdbtk_idle + } else { + gdbtk_idle + } + return 1 + } + } + + if {! [file exists $gdb_exe_name]} { + tk_messageBox -icon error -title GDB -type ok -modal task\ + -message "Request to download non-existent executable $gdb_exe_name" + set gdb_downloading 0 + gdbtk_idle + return 0 + } + + debug "downloading $gdb_exe_name" + + set target $gdb_target_name + + # get load info and total up number of bytes + if {[catch {gdb_load_info $gdb_exe_name} val]} { + set result "$gdb_exe_name: $val" + tk_dialog .load_warn "" "$result" error 0 Ok + return 0 + } + set i 0 + set total_bytes 0 + set section(names) {} + foreach x $val { + set s [lindex $x 0] + lappend section(names) $s + set section($s) $i + set b [lindex $x 1] + set bytes($i) [expr {double($b)}] + incr total_bytes $b + incr i + } + set num_sections $i + + set ::download_cancel_ok 0 + set ::download_start_time [clock seconds] + + + if {[pref getd gdb/load/$target-verbose] == "1"} { + # open a detailed download dialog window + set download_dialog [ManagedWin::open Download -transient -filename $gdb_exe_name] + } else { + # raise source windows + foreach src [ManagedWin::find SrcWin] { + $src reveal + $src toolbar downloading + } + set download_dialog "" + } + + set download_error "" + debug "starting load" + ::update idletasks + if {[catch {gdb_cmd "load $gdb_exe_name"} errTxt]} { + debug "load returned $errTxt" + if {[regexp -nocase cancel $errTxt]} { + set download_error "CANCEL" + } else { + set download_error $errTxt + } + set ::download_cancel_ok 1 + } + + debug "Done loading" + + set gdb_downloading 0 + if {$::download_cancel_ok} { + set gdb_loaded 0 + if {$download_dialog != ""} { + catch {$download_dialog done $download_error} + } + } else { + set gdb_loaded 1 + if {$download_dialog != ""} { + catch {$download_dialog done} + } + } + + foreach src [ManagedWin::find SrcWin] { + if {$download_error == "CANCEL"} { + $src download_progress CANCEL 1 1 + } else { + $src download_progress DONE 0 $total_bytes $download_error + } + } + + set ::download_cancel_ok 0 + set download_dialog "" + + gdbtk_idle + return 0 +} diff --git a/gdb/gdbtk/library/download.ith b/gdb/gdbtk/library/download.ith new file mode 100644 index 00000000000..9add1e71dad --- /dev/null +++ b/gdb/gdbtk/library/download.ith @@ -0,0 +1,39 @@ +# Download class definition for GDBtk. +# Copyright 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class Download { + inherit ManagedWin + + protected { + common total_bytes + common section + common bytes + common num_sections + proc dont_remember_size {} { return 1} + } + public { + variable filename + + method constructor {args} + method destructor {} + method update_download { sec num tot } + method done { {msg ""} } + method cancel {} + + proc download_it { } + proc do_download_hooks {} + proc download_hash { section num } + + } +} diff --git a/gdb/gdbtk/library/embeddedwin.ith b/gdb/gdbtk/library/embeddedwin.ith new file mode 100644 index 00000000000..5018cc6f972 --- /dev/null +++ b/gdb/gdbtk/library/embeddedwin.ith @@ -0,0 +1,25 @@ +# EmbeddedWin class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class EmbeddedWin { + inherit ManagedWin + + constructor {args} { + debug "EmbeddedWin::constructor $args" + } + + destructor { + debug "EmbeddedWin::destructor" + } +} diff --git a/gdb/gdbtk/library/gdbwin.ith b/gdb/gdbtk/library/gdbwin.ith new file mode 100644 index 00000000000..06c7d2d1369 --- /dev/null +++ b/gdb/gdbtk/library/gdbwin.ith @@ -0,0 +1,26 @@ +# GDBwin class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class GDBWin { + private variable _state + public method update + + constructor {args} { + debug "GDBWin::constructor $args" + } + + destructor { + debug "GDBWin::destructor" + } +} diff --git a/gdb/gdbtk/library/globalpref.itb b/gdb/gdbtk/library/globalpref.itb new file mode 100644 index 00000000000..cd61e90694e --- /dev/null +++ b/gdb/gdbtk/library/globalpref.itb @@ -0,0 +1,401 @@ +# Global preference class implementation for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements Global preferences dialog +# +# ---------------------------------------------------------------------- + +# ------------------------------------------------------------------ +# PROC: _init - set up the tracing labels info +# ------------------------------------------------------------------ +body GlobalPref::_init {} { + if {$inited} { + return + } + + set inited 1 + + array set tracing_labels { + 0 "Tracing features disabled" + 1 "Tracing features enabled" + max_len 0 + } + + foreach elem [array names tracing_labels] { + set len [string length $tracing_labels($elem)] + set tracing_labels(max_len) \ + [expr $len > $tracing_labels(max_len) ? $len : $tracing_labels(max_len) ] + } +} + +# ------------------------------------------------------------------ +# METHOD: constructor - create the Global Preferences object +# ------------------------------------------------------------------ +body GlobalPref::constructor {args} { + window_name "Global Preferences" + _init + build_win + eval itk_initialize $args +} + +# ------------------------------------------------------------------ +# METHOD: destructor - destroy the Global Preferences object +# ------------------------------------------------------------------ +body GlobalPref::destructor {} { + foreach thunk $Fonts { + font delete test-$thunk-font + } +} + +# ------------------------------------------------------------------ +# METHOD: build_win - build the dialog +# ------------------------------------------------------------------ +body GlobalPref::build_win {} { + global tcl_platform GDBTK_LIBRARY + debug + frame $itk_interior.f + frame $itk_interior.x + set frame $itk_interior.f + + # Icons + frame $frame.icons + label $frame.icons.lab -text "Icons " + combobox::combobox $frame.icons.cb -editable 0 -maxheight 10\ + -command [code $this change_icons] + + # get list of icon directories + set icondirlist "" + cd $GDBTK_LIBRARY + foreach foo [glob -- *] { + if {[file isdirectory $foo] && [file exists [file join $foo "icons.txt"]]} { + lappend icondirlist $foo + } + } + + set width 14 + # load combobox + set imagedir [pref get gdb/ImageDir] + foreach dir $icondirlist { + if {![string compare $dir $imagedir]} { + set cdir 1 + } else { + set cdir 0 + } + set foo [file join $dir "icons.txt"] + if {[catch {::open $foo r} fid]} { + # failed + if {$cdir} {$frame.icons.cb entryset "unknown icons"} + $frame.icons.cb list insert end "unknown icons" + } else { + if {[gets $fid txt] >= 0} { + if {$cdir} {$frame.icons.cb entryset $txt} + if {[string length $txt] > $width} {set width [string length $txt]} + $frame.icons.cb list insert end $txt + } else { + if {$cdir} {$frame.icons.cb entryset "unknown icons"} + $frame.icons.cb list insert end "unknown icons" + } + close $fid + } + } + $frame.icons.cb configure -width $width + + + # searching for fixed font families take a long time + # therefore, we cache the font names. The font cache + # can be saved in the init file. A way should be provided + # to rescan the font list, without deleting the entry from the + # init file. + set font_cache [pref get gdb/font_cache] + if {$font_cache == ""} { + if {$tcl_platform(platform) == "unix"} { + toplevel .c + wm title .c "Scanning for fonts" + message .c.m -width 3i -text "Scanning system for fonts\n\nPlease wait..." \ + -relief flat -padx 30 -pady 30 \ + -bg [pref get gdb/global_prefs/message_bg] \ + -fg [pref get gdb/global_prefs/message_fg] + ::update + pack .c.m + focus .c + ::raise .c + ::update + } + set fam [font families] + foreach fn $fam { + if {[font metrics [list $fn] -fixed] == 1} { + lappend font_cache $fn + } + } + pref set gdb/font_cache $font_cache + if {$tcl_platform(platform) == "unix"} { destroy .c } + } + + Labelledframe $frame.d -text "Fonts" + set f [$frame.d get_frame] + + make_font_item $f fixed "Fixed Font:" $font_cache + + if {$tcl_platform(platform) != "windows"} { + # Cannot change the windows menu font ourselves + make_font_item $f menu "Menu Font:" [font families] + } + + make_font_item $f default "Default Font:" [font families] + make_font_item $f status "Status Bar Font:" [font families] + + # This is the tracing preference + set tracing_cb [pref get gdb/mode] + if { ![info exists tracing_labels($tracing_cb)]} { + debug "Got unknown mode value: $tracing_cb" + set tracing_labels($tracing_cb) "Unknown gdb mode..." + } + + frame $frame.tracing + checkbutton $frame.tracing.cb -variable [scope tracing_cb] \ + -text $tracing_labels($tracing_cb) \ + -command [code $this toggle_tracing $frame.tracing.cb] \ + -width $tracing_labels(max_len) -anchor w + pack $frame.tracing.cb -pady 10 -side left -fill none + + # help browser preferences + if {$tcl_platform(platform) == "windows"} { + set help_text "Use Internet Browser to View Help Files" + } else { + set help_text "Use Netscape to View Help Files" + } + frame $frame.browser + checkbutton $frame.browser.cb \ + -text $help_text -variable [pref varname gdb/help/browser] + pack $frame.browser.cb -pady 10 -side left -fill none + + # use_icons + if {$tcl_platform(platform) == "unix"} { + frame $frame.use_icons + checkbutton $frame.use_icons.cb \ + -text "Use builtin image as icon." -variable [pref varname gdb/use_icons] + pack $frame.use_icons.cb -pady 10 -side left -fill none + } + + pack $frame.icons.lab $frame.icons.cb -side left + pack $frame.icons -side top -padx 10 -pady 10 + pack $frame.tracing -side top -fill x -expand 0 -side bottom + pack $frame.browser -side top -fill x -expand 0 -side bottom + if {$tcl_platform(platform) == "unix"} { + pack $frame.use_icons -side top -fill x -expand 0 -side bottom + } + pack $frame.d -side top -fill both -expand yes + + # make buttons + button $itk_interior.x.ok -text OK -underline 0 -width 7 -command [code $this ok] + button $itk_interior.x.apply -text Apply -width 7 -underline 0 -command [code $this apply] + button $itk_interior.x.cancel -text Cancel -width 7 -underline 0 -command [code $this cancel] + pack $itk_interior.x.ok $itk_interior.x.apply $itk_interior.x.cancel -side left + standard_button_box $itk_interior.x + pack $itk_interior.x -fill x -padx 5 -pady 5 -side bottom + + + pack $itk_interior.f -fill both -expand yes -padx 10 -pady 5 + + bind $itk_interior.x.ok <Return> \ + "$itk_interior.x.ok flash; $itk_interior.x.ok invoke" + focus $itk_interior.x.ok + + # We don't want the window flashing around as we change the fonts... + + ::update idletasks + + resize_font_item_height + pack propagate $itk_interior.f 0 + +} +# ------------------------------------------------------------------ +# PRIVATE METHOD: make_font_item +# ------------------------------------------------------------------ +body GlobalPref::make_font_item {f name label font_list} { + + # create ComboBox with font name + lappend Fonts $name + + set Original($name,family) [font actual global/$name -family] + set Original($name,size) [font actual global/$name -size] + font create test-$name-font -family $Original($name,family) \ + -size $Original($name,size) + label $f.${name}x -text $label + + combobox::combobox $f.${name}n -editable 0 -value $Original($name,family) \ + -command [code $this wfont_changed family $name] + + foreach a $font_list { + $f.${name}n list insert end $a + } + + tixControl $f.${name}s -label Size: -integer true -max 18 -min 6 \ + -value $Original(${name},size) -command [code $this font_changed size $name] + [$f.${name}s subwidget entry] configure -width 2 + label $f.${name}l -text ABCDEFabcdef0123456789 -font test-$name-font + + grid $f.${name}x $f.${name}n $f.${name}s $f.${name}l -sticky we -padx 5 -pady 5 + grid columnconfigure $f 3 -weight 1 + +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: resize_font_item_height +# ------------------------------------------------------------------ +body GlobalPref::resize_font_item_height {} { + foreach font $Fonts { + set master [$itk_interior.f.d get_frame] + set row [gridCGet $master.${font}l -row] + grid rowconfigure $master $row -minsize [lindex [grid bbox $master 0 $row 3 $row ] 3] + } +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: change_icons +# ------------------------------------------------------------------ +body GlobalPref::change_icons {w args} { + global gdb_ImageDir GDBTK_LIBRARY + set index [$w list curselection] + if {$index != ""} { + set dir [lindex $icondirlist $index] + pref set gdb/ImageDir $dir + set gdb_ImageDir [file join $GDBTK_LIBRARY $dir] + ManagedWin::restart + } +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: wfont_changed - callback from font comboboxes +# PRIVATE METHOD: font_changed - callback from font tixControls +# ------------------------------------------------------------------ +body GlobalPref::wfont_changed {attribute font w val} { + font_changed $attribute $font $val +} + +body GlobalPref::font_changed {attribute font val} { + # val will be a size or a font name + + switch $attribute { + size { + set oldval [font configure test-$font-font -size] + font configure test-$font-font -size $val + } + + family { + set oldval [font configure test-$font-font -family] + font configure test-$font-font -family $val + } + + default { debug "GlobalPref::font_changed -- invalid change" } + } +} + +# ------------------------------------------------------------------ +# METHOD: toggle_tracing_mode - toggles the tracing mode on and off +# ------------------------------------------------------------------ +body GlobalPref::toggle_tracing_mode {} { + pref set gdb/mode $tracing_cb + # Reset the button-1 behavior if you are going out of trace mode. + if {!$tracing_cb} { + pref set gdb/B1_behavior 1 + } +} + +body GlobalPref::toggle_tracing {win} { + debug foo + $win configure -text $tracing_labels($tracing_cb) +} + +# ------------------------------------------------------------------ +# METHOD: ok - called to accept settings and close dialog +# ------------------------------------------------------------------ +body GlobalPref::ok {} { + apply 1 +} + +# ------------------------------------------------------------------ +# METHOD: apply - apply current settings to the screen +# ------------------------------------------------------------------ +body GlobalPref::apply {{deleteMe 0}} { + set commands {} + + # If you are not destroying the window, then make sure to + # propagate the geometry info from the font frame, so that changing + # the fonts IN the window don't cause some of the buttons to + # get obscured... + + if {!$deleteMe} { + pack propagate $itk_interior.f 1 + } + + foreach thunk $Fonts { + set font [font configure test-$thunk-font] + if {[pref get global/font/$thunk] != $font} { + lappend commands [list pref set global/font/$thunk $font] + } + } + + if {[pref get gdb/mode] != $tracing_cb} { + lappend commands toggle_tracing_mode + } + + if {[llength $commands] > 0} { + foreach command $commands { + eval $command + } + if {$deleteMe} { + unpost + } + ManagedWin::restart + return + } + if {$deleteMe} { + unpost + } else { + after idle " + update idletasks + [code $this resize_font_item_height] + pack propagate $itk_interior.f 0 + " + } +} + +# ------------------------------------------------------------------ +# METHOD: cancel - forget current settings -- reset to original +# state and close preferences +# ------------------------------------------------------------------ +body GlobalPref::cancel {} { + # Reset fonts if different + set commands {} + foreach thunk $Fonts { + set family [font configure global/$thunk -family] + set size [font configure global/$thunk -size] + if {$Original($thunk,family) != $family || $Original($thunk,size) != $size} { + lappend commands [list pref set global/font/$thunk \ + [list -family $Original($thunk,family) -size $Original($thunk,size)]] + } + } + + if {[llength $commands] > 0} { + foreach command $commands { + eval $command + } + } + if {[llength $commands] > 0} { + ManagedWin::restart + } + unpost +} diff --git a/gdb/gdbtk/library/globalpref.ith b/gdb/gdbtk/library/globalpref.ith new file mode 100644 index 00000000000..34ef45e77a0 --- /dev/null +++ b/gdb/gdbtk/library/globalpref.ith @@ -0,0 +1,45 @@ +# Global preference class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class GlobalPref { + inherit ManagedWin ModalDialog + + private { + variable icondirlist "" + variable Original ;# Original settings + variable Fonts ;# List of all available fonts for editing + common tracing_labels + common inited 0 + variable tracing_cb + + proc _init {} + method build_win {} + method make_font_item {f name label font_list} + method resize_font_item_height {} + method change_icons {w args} + method wfont_changed {attribute font w val} + method font_changed {attribute font val} + method toggle_tracing_mode {} + method ok {} + method apply {{deleteMe 0}} + method cancel {} + method toggle_tracing {win} + } + + public { + method constructor {args} + method destructor {} + } + +} diff --git a/gdb/gdbtk/library/help/breakpoint.html b/gdb/gdbtk/library/help/breakpoint.html new file mode 100644 index 00000000000..443237a6970 --- /dev/null +++ b/gdb/gdbtk/library/help/breakpoint.html @@ -0,0 +1,107 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + <META NAME="GENERATOR" CONTENT="Mozilla/4.06 [en] (X11; I; Linux 2.0.35 i686) [Netscape]"> + <TITLE>Breakpoint Window Help</TITLE> +</HEAD> +<BODY> + +<H1>The Breakpoint Window</H1> +The Breakpoint Window lists all the various breakpoints that exist in the +program. It facilitates modifying breakpoints (make them temporary or normal, +disabled or enabled) and removing breakpoints. +<UL> +<LI><A HREF="#menus_bp">Breakpoint Menu</A></LI> +<LI><A HREF="#menus_global">Global Menu</A></LI> +<LI><A HREF="#display">Breakpoint Display</A></LI> +</UL> + +<HR SIZE=4 WIDTH="100%"> + +<H2> +<A NAME="menus_bp"></A>Breakpoint Menu</H2> +The Breakpoint Menu operates on the selected breakpoint only. If +no breakpoint is selected the menu items will be disabled. The type and +state of a breakpoint may be changed by selecting the desired type or state +from the menu. +<DL> +<DT>Normal</DT> +<DD>The selected breakpoint is a normal breakpoint</DD> +<DT>Temporary</DT> +<DD>Indicates that the breakpoint is temporary</DD> +<DT>Enabled</DT> +<DD>The breakpoint is active and will stop the debugger when it is hit.</DD> +<DT>Disabled</DT> +<DD>The breakpoint is being ignored. A disabled breakpoint will never get hit.</DD> +<DT>Remove</DT> +<DD>Deletes the breakpoint</DD> +</DL> + +<HR SIZE=4 WIDTH="100%"> +<H2> +<A NAME="menus_global"></A>Global Menu</H2> +Items on the Global Menu affect all defined breakpoints. Users may: +<DL> +<DT>Show Threads</DT> +<DD>Toggle on/off the thread column</DD> +<DT>Enable All</DT> +<DD>Enable all breakpoints</DD> +<DT>Disable All</DT> +<DD>Disable all breakpoints</DD> +<DT>Remove All</DT> +<DD>Delete all breakpoints</DD> +</DL> + +<HR SIZE=4 WIDTH="100%"> + +<H2><A NAME="display"></A>Breakpoint Display</H2> +The Breakpoint Display is a table of breakpoints. The first column of the +table (unlabeled) shows a checkbutton, indicating whether the breakpoint +is enabled (checked) or disabled (unchecked). Disabled breakpoints are +ignored and will not cause the program to stop. +<P>To use the Breakpoint Menu or the Breakpoint Pop-up Menu, first use +the left mouse button to select a breakpoint from the list, then make the +menu selection. + +<H4>Modifying Breakpoints</H4> +To <A NAME="display_state"></A>enable a breakpoint, simply click the +checkbutton in the first column of the desired breakpoint so that it is +selected (checked). To disable a breakpoint, "uncheck" the checkbutton. +<P>To change a breakpoint's <A NAME="display_temp"></A>type, select +the desired type from either the Breakpoint Menu or the Breakpoint Pop-up +Menu. +<P>To remove a <A NAME="display_remove"></A>breakpoint, use the left +mouse button to select the breakpoint to remove and use either the Breakpoint +Menu or the Breakpoint Pop-up Menu to select "remove". To re-install a +breakpoint, use the <A HREF="source.html#setting_a_breakpoint">Source Window +Display</A>. + +<H4><A NAME="display_popup"></A>Breakpoint Pop-up Menu</H4> +The Breakpoint Pop-up Menu is accessed by using the mouse cursor to select +a breakpoint from the Breakpoint Display and then clicking the right button +on the mouse. The Pop-up allows expert users quicker access to the functions +of the Breakpoint Menu: +<DL> +<DT>Normal</DT> +<DD>The selected breakpoint is a normal breakpoint</DD> +<DT>Temporary</DT> +<DD>Indicates that the breakpoint is temporary</DD> +<DT>Enabled</DT> +<DD>The breakpoint is active and will stop the debugger when it is hit.</DD> +<DT>Disabled</DT> +<DD>The breakpoint is being ignored. A disabled breakpoint will never get hit.</DD> +<DT>Remove</DT> +<DD>Deletes the breakpoint</DD> +<DT>Global, Show Threads</DT> +<DD>Toggle on/off the thread column</DD> +<DT>Global, Enable All</DT> +<DD>Enable all breakpoints</DD> +<DT>Global, Disable All</DT> +<DD>Disable all breakpoints</DD> +<DT>Global, Remove All</DT> +<DD>Delete all breakpoints</DD> +</DL> + +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/browser.html b/gdb/gdbtk/library/help/browser.html new file mode 100644 index 00000000000..a6a731f9925 --- /dev/null +++ b/gdb/gdbtk/library/help/browser.html @@ -0,0 +1,82 @@ +<HTML> +<HEAD> +<TITLE>Function Browser Help</TITLE> +</HEAD> +<BODY> +<CENTER><H1>The Function Browser</H1></CENTER> +<BR>The Function Browser may be used to search for specific functions +in the executable, allowing the user to easily browse through source +code and set and clear breakpoints at anywhere in the executable +with ease. + +<H3><A HREF="#display">Function Browser Display</A></H3> +<UL> + <LI><A HREF="#display_search">Searching for a Function</A> + <LI><A HREF="#display_limit">Limiting the Search</A> + <LI><A HREF="#display_break">Toggling Breakpoints</A> + <LI><A HREF="#display_source">Viewing Source Code</A> +</UL></P> + +<H2><A NAME="display">Function Browser Display</A></H2> +The Function Browser display shows all the current search +parameters specified by the user: search type, search expression, +and files to search. + +<H4><A NAME="display_search">Searching for a Function</A></H4> +To search for a function, enter +the name of the function into the "Search for" field at the top +of the Function Browser and press the Enter key on the keyboard +or press the Search button in the lower right-hand corner. The +Function Browser searches through every file contained in the +executable (including libraries and included files) for the +specified function. If the function is found in the executable's +symbol table, the Functions listing will contain the function's +name. + +<H4><A NAME="display_limit">Limiting the Search</A></H4> +Searches are not confined to one specific function. The Function +Browser is capable of searching for any function which matches +the expression entered into the "Search for" field. For example, +to list all functions which start with the letters c, y, and g, +enter "cyg" into the search field and press enter. Every function +which begins with these three letters is displayed. To search +for all functions which do <I>not</I> begin with the letters "a", +"b", and "c", enter the regular expression "^[^a-c]" into the search +field, click the "Use regular expression" checkbox, and then click +Search (or press the Enter key on the keyboard). The Browser returns +the names of all matching functions. + +<P>Additionally, any search may be limited in two more ways: +the Browser may be configured to search only specified files and +list only static functions.</P> + +<P>To search specific files only, select the files to be searched +using the Files list. To select all files for searching, click the +Select All button at the bottom of the Files listing. Note that +the Select All button changes to Select None, allowing the user to +deselect all selected files. With no files selected, the Browser +will search all files in the project.</P> + +<P>To search for static functions only, click the "Only show +functions declared 'static'" before searching.</P> + +<H4><A NAME="display_break">Toggling Breakpoints</A></H4> +There are numerous ways to toggle +breakpoints on functions using the Function Browser. To toggle the +breakpoint at all listed matches in the Functions list, press the +Toggle Breakpoint button. To toggle a breakpoint at some subset +of functions listed in the Functions list, click the right mouse +button on each function's name in the list. The last way to toggle +breakpoints using the function browser involves viewing the function's +source code. + +<H4><A NAME="display_source">Viewing Source Code</A></H4> +To view the source code for a function, +select the function in the Functions list and click the "View Source" +dropdown (if it is not already dropped down). A Source Viewer +similar to the <A HREF="source.html#display">Source Window Display</A> +appears at the bottom. Toggle breakpoints as described in +<A HREF="source.html#setting_a_breakpoint">Setting a Breakpoint</A> +in <A HREF="source.html">Source Window Help</A>. +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/console.html b/gdb/gdbtk/library/help/console.html new file mode 100644 index 00000000000..d0fdfba52e1 --- /dev/null +++ b/gdb/gdbtk/library/help/console.html @@ -0,0 +1,74 @@ +<HTML> + <HEAD> + <TITLE>Console Window Help</TITLE> + </HEAD> + <BODY> + <CENTER><H2>The Console Window</H2></CENTER> + + <P>The Console Window provides the traditional command-line interface to GDB. + It is very similar to the command-line you get when GDB is run with "-nw".</P> + + <UL> + <LI><A HREF="#display">Console Display</A></LI> + <LI><A HREF="#editing">Editing Commands</A></LI> + <LI><A HREF="#history">History Commands</A></LI> + <LI><A HREF="#display_hlp">Getting Help</A></LI> + </UL> + + <H4><A NAME="display">Console Display</A></H4> + The Console Display is simply a scrolled window in which the debugger prompt + appears. By default, the prompt is set to "(gdb) ", but it may be changed via a + command line option. + + <P>To execute commands in the console window, simply enter + the command in the display. If the debugger is busy, the message "Error: The + debugger is busy." appears informing the user that the command was not accepted.</P> + + <P>Whenever a command is executed, the debugger's windows will update to display + any new state information. Any output from the command is also echoed to the Console + Window for ease of use. If an error occurs, an error message is printed to the Console + Window. All error messages appear in the Console Window using a red typeface. + </P> + + <BR> + + <H4><A NAME="editing">Editing Commands</A></H4> + <P>The Console Window shell has many powerful features to help edit commands.</P> + <UL> + <LI> Return or Enter causes the command to be executed. + + <LI> Control-A moves the cursor to the beginning of the line.</LI> + <LI> Control-E moves the cursor to the end of the line.</LI> + <LI> Control-D or DELETE delete the character to the right of the cursor.</LI> + <LI> BACKSPACE deletes the character to the left of the cursor.</LI> + <LI> Control-B or LeftArrow moves the cursor to the left.</LI> + <LI> Control-F or RightArrow moves the cursor to the right.</LI> + <LI> Control-K deletes everything to the right of the cursor.</LI> + <LI> Control-U deletes the text between the cursor and the start of the line.</LI> + <LI> Control-W deletes the previous word</LI> + <LI> END deletes the whole line.</LI> + <LI> The mouse may also be used to position the cursor and cut and paste.</LI> + </UL> + + <H4><A NAME="history">History Commands</A></H4> + <UL> + <LI> Conrol-P or UpArrow recalls the previous command.</LI> + <LI> Conrol-N or DownArrow recalls the next command.</LI> + <LI> Shift-UpArrow or Control-UpArrow will search through previous commands + for commands that start with the same characters as the current line. For + example, if you type "pr" and hit Shift-UpArrow, it may find commands in the + history such as "print foo" or "print sol[x]". Each time you search it will + go back further in the history. If nothing is on the current line, it + acts just like Control-P or UpArrow.</LI> + <LI> Shift-DownArrow or Control-DownArrow work in the opposite direction of + Shift-UpArrow and Control-DownArrow. </LI> + </UL> + + <BR> + + <H4><A NAME="display_hlp">Getting Help</A></H4> + The Console Window has its own online help system. To access the help system, enter + "help" at the prompt and follow the on-screen instructions. For more help, please + consult the <!-- What is this really called? --> <I>GDB User's Guide</I>. + </BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/debug.html b/gdb/gdbtk/library/help/debug.html new file mode 100644 index 00000000000..11b9979deca --- /dev/null +++ b/gdb/gdbtk/library/help/debug.html @@ -0,0 +1,131 @@ +<HTML> +<HEAD> +<TITLE>Debugging Help</TITLE> +</HEAD> +<BODY> +<H2>GDBTK Debugging Functions</H2> +<H4>Overview</H4> +<P> This describes the basic internal functions for debugging GDBTK.</P> + +<H4>Environment Variables</H4> +<P><BOLD>GDBTK_DEBUG</BOLD> - Setting this variable controls the Debug +window.</P> +<P><BOLD>GDBTK_DEBUG</BOLD> may have the following values:</P> +<DL> +<DT>0 or unset</DT> +<DD>The Debug window is not opened and not listed on the menu. (You +may still open it by typing Ctrl-U in the source window.)</DD> +<DT>1</DT> +<DD>The Debug window is listed on the menu, but not opened.</DD> +<DT>2</DT> +<DD>The Debug window is opened at startup.</DD> +</DL> + +<HR> +<P><BOLD>GDBTK_TRACE</BOLD> - This variable determines if tracing is enbabled. +Tracing may only be enabled at GDBTK startup. Changing <BOLD>GDBTK_TRACE</BOLD> +while GDBTK is running has no effect.</P> +<P><BOLD>GDBTK_TRACE</BOLD> may have the following values:</P> +<DL> +<DT>0 or unset</DT> +<DD>Tracing is not enabled.</DD> +<DT>1</DT> +<DD>Tracing is enabled, but not started. To start tracing, you need to do +so in the Debug Window or from the console. (The command to do this is "tk +::debug::trace_start).</DD> +<DT>2</DT> +<DD>Tracing is enabled and started immediately.</DT> +</DL> + +<P><BOLD>GDBTK_DEBUGFILE</BOLD> - This variable contains an optional filename +where GDBTK will write all debugging information. This information will include +the output of all "debug" and "dbug" commands, as well as tracing, if it is +enabled. The value of +<BOLD>GDBTK_DEBUGFILE</BOLD> will not change what is displayed in the Debug +Window, with one exception; when the Debug Window is opened, it will read +the contents of <BOLD>GDBTK_DEBUGFILE</BOLD> (if it is set and not "stdout"). +<P><BOLD>GDBTK_DEBUGFILE</BOLD> may have the following values:</P> +<DL> +<DT>unset</DT> +<DD>No information will be logged.</DD> +<DT><italic>filename</italic></DT> +<DD>Debugging information will be logged to <italic>filename</italic>. +<DT>"stdout"</DT> +<DD>Debugging information will be written to stdout</DD> +</DL> +<HR> +<H4>Tcl Debugging Functions</H4> +<P> All debugging functions have been moved into debug.tcl in the ::debug +namespace. "debug" and "dbug" are imported into the global namespace.</P> +<P> The following are the standard debug message functions.</P> +<code> +# ----------------------------------------------------------------------------- +# NAME: debug::debug +# +# SYNOPSIS: debug { {msg ""} } +# +# DESC: Writes a message to the proper output. The priority of the +# message is assumed to be "I" (informational). This function +# is provided for compatibility with the previous debug function. +# For higher priority messages, use dbug. +# +# ARGS: msg - Message to be displayed. +# ----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- +# NAME: debug::dbug +# +# SYNOPSIS: dbug { level msg } +# +# DESC: Writes a message to the proper output. Unlike debug, this +# function take a priority level. +# +# ARGS: msg - Message to be displayed. +# level - One of the following: +# "I" - Informational only +# "W" - Warning +# "E" - Error +# "X" - Fatal Error +# ---------------------------------------------------------------------------- +</code> +<P> These next functions are used to trace variables, which should not be +confused with the functions tracing.<P> +<code> +# ---------------------------------------------------------------------------- +# NAME: debug::trace_var +# SYNOPSIS: debug::trace_var {varName mode} +# DESC: Sets up variable trace. When the trace is activated, +# debugging messages will be displayed. +# ARGS: varName - the variable name +# mode - one of more of the following letters +# r - read +# w - write +# u - unset +# ---------------------------------------------------------------------------- +# ---------------------------------------------------------------------------- +# NAME: debug::remove_trace +# SYNOPSIS: debug::remove_trace {var mode} +# DESC: Removes a trace set up with "trace_var". +# ---------------------------------------------------------------------------- +# ---------------------------------------------------------------------------- +# NAME: debug::remove_all_traces +# SYNOPSIS: debug::remove_all_traces +# DESC: Removes all traces set up with "trace_var". +# ---------------------------------------------------------------------------- +</code> +<P> The following two functions may be used to start and stop tracing +programmatically.</P> +<code> +# ----------------------------------------------------------------------------- +# NAME: ::debug::trace_start +# SYNOPSIS: ::debug::trace_start +# DESC: Starts logging of function trace information. +# ----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- +# NAME: ::debug::trace_stop +# SYNOPSIS: ::debug::trace_stop +# DESC: Stops logging of function trace information. +# ----------------------------------------------------------------------------- +</code> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/gbl_pref.html b/gdb/gdbtk/library/help/gbl_pref.html new file mode 100644 index 00000000000..2760750c4e9 --- /dev/null +++ b/gdb/gdbtk/library/help/gbl_pref.html @@ -0,0 +1,20 @@ +<HTML> +<HEAD> +<TITLE>Global Preferences Help</TITLE> +</HEAD> +<BODY> +<H1>Global Preferences</H1> +<H3>Overview</H3> +<P>Not yet done.</P> + +<P>Global Preferences topics: +<UL> + <LI><UL><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + </UL> +</UL></P> + +<H3><A NAME="">stuff</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/help.html b/gdb/gdbtk/library/help/help.html new file mode 100644 index 00000000000..3a3640da1a1 --- /dev/null +++ b/gdb/gdbtk/library/help/help.html @@ -0,0 +1,32 @@ +<HTML> +<HEAD> +<TITLE>Help Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Help Window</H1> +<H2>Overview</H2> +<P>This is some nice text which describes the help window, its role +in deugging, and perhaps some of the nifty things people can do with +this window.</P> + +<P>Help Window topics: +<UL> + <LI><UL><A HREF="#menus">Menus</A> + <LI><A HREF="#menus_file">File Menu</A> + <LI><A HREF="#menus_topics">Topics Menu</A> + </UL> + <LI><UL><A HREF="#display">Help Display</A> + <LI><A HREF="#display_nav">Navigating the Help Window</A> + <LI><A HREF="#display_link">Definition and Page Links</A> + </UL> +</UL></P> + +<H2><A NAME="menus">Menus</A></H2> +<H3><A NAME="menus_file">File Menu</A></H3> +<H3><A NAME="menus_topics">Topics Menu</A></H3> + +<H3><A NAME="display">Help Display</A></H3> +<H3><A NAME="display_nav">Navigating the Help Window</A></H3> +<H3><A NAME="display_link">Definition and Page Links</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/images/frame_info.gif b/gdb/gdbtk/library/help/images/frame_info.gif Binary files differnew file mode 100644 index 00000000000..3da109f84b6 --- /dev/null +++ b/gdb/gdbtk/library/help/images/frame_info.gif diff --git a/gdb/gdbtk/library/help/images/index.gif b/gdb/gdbtk/library/help/images/index.gif Binary files differnew file mode 100644 index 00000000000..34d116b6300 --- /dev/null +++ b/gdb/gdbtk/library/help/images/index.gif diff --git a/gdb/gdbtk/library/help/images/mem_menu.gif b/gdb/gdbtk/library/help/images/mem_menu.gif Binary files differnew file mode 100644 index 00000000000..bf874f3d4ff --- /dev/null +++ b/gdb/gdbtk/library/help/images/mem_menu.gif diff --git a/gdb/gdbtk/library/help/images/mem_popup.gif b/gdb/gdbtk/library/help/images/mem_popup.gif Binary files differnew file mode 100644 index 00000000000..a1387146934 --- /dev/null +++ b/gdb/gdbtk/library/help/images/mem_popup.gif diff --git a/gdb/gdbtk/library/help/images/mem_pref.gif b/gdb/gdbtk/library/help/images/mem_pref.gif Binary files differnew file mode 100644 index 00000000000..4fc8a5aaa6e --- /dev/null +++ b/gdb/gdbtk/library/help/images/mem_pref.gif diff --git a/gdb/gdbtk/library/help/images/src_bal.gif b/gdb/gdbtk/library/help/images/src_bal.gif Binary files differnew file mode 100644 index 00000000000..51871bcc7f1 --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_bal.gif diff --git a/gdb/gdbtk/library/help/images/src_bp_bal.gif b/gdb/gdbtk/library/help/images/src_bp_bal.gif Binary files differnew file mode 100644 index 00000000000..1f6205ac2e5 --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_bp_bal.gif diff --git a/gdb/gdbtk/library/help/images/src_bpop.gif b/gdb/gdbtk/library/help/images/src_bpop.gif Binary files differnew file mode 100644 index 00000000000..c9e4d099d28 --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_bpop.gif diff --git a/gdb/gdbtk/library/help/images/src_menu.gif b/gdb/gdbtk/library/help/images/src_menu.gif Binary files differnew file mode 100644 index 00000000000..8fba6aea810 --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_menu.gif diff --git a/gdb/gdbtk/library/help/images/src_pop.gif b/gdb/gdbtk/library/help/images/src_pop.gif Binary files differnew file mode 100644 index 00000000000..8794c0a5908 --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_pop.gif diff --git a/gdb/gdbtk/library/help/images/src_stat.gif b/gdb/gdbtk/library/help/images/src_stat.gif Binary files differnew file mode 100644 index 00000000000..eab58188edc --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_stat.gif diff --git a/gdb/gdbtk/library/help/images/src_thread.gif b/gdb/gdbtk/library/help/images/src_thread.gif Binary files differnew file mode 100644 index 00000000000..99203ccd8c8 --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_thread.gif diff --git a/gdb/gdbtk/library/help/images/src_toolbar.gif b/gdb/gdbtk/library/help/images/src_toolbar.gif Binary files differnew file mode 100644 index 00000000000..d6801b3edf5 --- /dev/null +++ b/gdb/gdbtk/library/help/images/src_toolbar.gif diff --git a/gdb/gdbtk/library/help/index.html b/gdb/gdbtk/library/help/index.html new file mode 100644 index 00000000000..33571af34ed --- /dev/null +++ b/gdb/gdbtk/library/help/index.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + <META NAME="GENERATOR" CONTENT="Mozilla/4.07 [en] (X11; I; Linux 2.0.35 i686) [Netscape]"> + <TITLE>Help Index</TITLE> +</HEAD> +<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000"> + +<CENTER><IMG SRC="images/index.gif" HEIGHT=123 WIDTH=335></CENTER> + +<UL> +<LI> +<A HREF="breakpoint.html">Breakpoint Window</A></LI> + +<LI> +<A HREF="console.html">Console Window</A></LI> + +<LI> +<A HREF="browser.html">Function Browser</A></LI> + +<LI> +<A HREF="locals.html">Locals Window</A></LI> + +<LI> +<A HREF="memory.html">Memory Window</A></LI> + +<LI> +<A HREF="register.html">Register Window</A></LI> + +<LI> +<A HREF="source.html">Source Window</A></LI> + +<LI> +<A HREF="stack.html">Stack Window</A></LI> + +<LI> +<A HREF="target.html">Target Window</A></LI> + +<LI> +<A HREF="thread.html">Thread Window</A></LI> + +<LI> +<A HREF="watch.html">Watch Window</A></LI> + +</UL> +<A HREF="license.html">GNU General Public License</A> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/license.html b/gdb/gdbtk/library/help/license.html new file mode 100644 index 00000000000..6ce6c431ca3 --- /dev/null +++ b/gdb/gdbtk/library/help/license.html @@ -0,0 +1,305 @@ +<HTML> +<HEAD> +<TITLE>GNU General Public License</TITLE> +</HEAD><BODY> +<B>The GNU General Public License +<P></P> +</B>Version 2, June 1991 +<P></P> +Copyright © 1989, 1991 Free Software Foundation, Inc. +<BR>59 Temple Place / Suite 330, Boston, MA 02111-1307, USA +<P></P> +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. +<P></P> +<B>Preamble +<P></P> +</B>The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and +change free software to make sure the software is free for all its users. This General Public +License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some +other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, +too. +<P></P> +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change the +software or use pieces of it in new free programs; and that you know you can +do these things. +<P></P> +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. +<P></P> +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must show +them these terms so they know their rights. +<P></P> +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute and/or +modify the software. +<P></P> +Also, for each author's protection and ours, we want to make certain that everyone understands that +there is no warranty for this free software. If the software is modified by +someone else and passed on, we want its recipients to know that what they have is +not the original, so that any problems introduced by others will not reflect on +the original authors' reputations. +<P></P> +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for +copying, distribution and modification follow. +<P></P> +<B>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +<P></P> +</B>0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of this +General Public License. The `Program”, below, refers to any such program or work, and a `work based on the Program' means either the Program or any derivative work under copyright law: that is +to say, a work containing the Program or a portion of it, either verbatim or +with modifications and/or translated into another language. (Hereinafter, +translation is included without limitation in the term `modification'.) Each licensee is addressed as `you'. +<P></P> +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. +<P></P> +<OL><LI> You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the Program +a copy of this License along with the Program. +<P></P> +</OL>You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. +<P></P> +<OL START="2"><LI> You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: +<P></P> +</OL>a) You must cause the modified files to carry prominent notices stating that you +changed the files and the date of any change. +<P></P> +b) You must cause any work that you distribute or publish, that in whole or in +part contains or is derived from the Program or any part thereof, to be licensed +as a whole at no charge to all third parties under the terms of this License. +<P></P> +c) If the modified program normally reads commands interactively when run, you +must cause it, when started running for such interactive use in the most ordinary +way, to print or display an announcement including an appropriate copyright +notice and a notice that there is no warranty (or else, saying that you provide a +warranty) and that users may redistribute the program under these conditions, +and telling the user how to view a copy of this License. (Exception: if the +Program itself is interactive but does not normally print such an announcement, +your work based on the Program is not required to print an announcement.) +<P></P> +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and its +terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a work +based on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the entire whole, +and thus to each and every part regardless of who wrote it. +<P></P> +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on the +Program. +<P></P> +In addition, mere aggregation of another work not based on the Program with +the Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this License. +<P></P> +<OL START="3"><LI> You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: +<P></P> +</OL>a) Accompany it with the complete corresponding machine-readable source code, +which must be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, +<P></P> +b) Accompany it with a written offer, valid for at least three years, to give any +third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding source +code, to be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, +<P></P> +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for noncommercial +distribution and only if you received the program in object code or executable +form with such an offer, in accord with Subsection b above.) +<P></P> +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all the +source code for all modules it contains, plus any associated interface definition +files, plus the scripts used to control compilation and installation of the +executable. However, as a special exception, the source code distributed need not +include anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the operating +system on which the executable runs, unless that component itself accompanies the +executable. +<P></P> +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. +<P></P> +<OL START="4"><LI> You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate your +rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so long +as such parties remain in full compliance. +<P></P> +<LI> You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program or +its derivative works. These actions are prohibited by law if you do not accept +this License. Therefore, by modifying or distributing the Program (or any work +based on the Program), you indicate your acceptance of this License to do so, +and all its terms and conditions for copying, distributing or modifying the +Program or works based on it. +<P></P> +<LI> Each time you redistribute the Program (or any work based on the Program), the +recipient automatically receives a license from the original licensor to copy, +distribute or modify the Program subject to these terms and conditions. You +may not impose any further restrictions on the recipients' exercise of the rights granted herein. +<P></P> +</OL>You are not responsible for enforcing compliance by third parties to this +License. +<P></P> +<OL START="7"><LI> If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this +License. If you cannot distribute so as to satisfy simultaneously your obligations +under this License and any other pertinent obligations, then as a consequence +you may not distribute the Program at all. For example, if a patent license +would not permit royalty-free redistribution of the Program by all those who +receive copies directly or indirectly through you, then the only way you could +satisfy both it and this License would be to refrain entirely from distribution of +the Program. +<P></P> +</OL>If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and the +section as a whole is intended to apply in other circumstances. +<P></P> +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many people +have made generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that system; it is up +to the author/donor to decide if he or she is willing to distribute software +through any other system and a licensee cannot impose that choice. +<P></P> +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. +<P></P> +<OL START="8"><LI> If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this License +incorporates the limitation as if written in the body of this License. +<P></P> +<LI> The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. +<P></P> +</OL>Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and `any later version', you have the option of following the terms and conditions either of that +version or of any later version published by the Free Software Foundation. If the +Program does not specify a version number of this License, you may choose any +version ever published by the Free Software Foundation. +<P></P> +<OL><LI> If you wish to incorporate parts of the Program into other free programs whose +distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, write to +the Free Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status of all +derivatives of our free software and of promoting the sharing and reuse of software +generally. +<P></P> +</OL>NO WARRANTY +<P></P> +<OL><LI> BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE +PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED +IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM `AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. +<P></P> +<LI> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY +COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +<P></P> +</OL>END OF TERMS AND CONDITIONS +<P></P> +<B>How to Apply These Terms to Your New Programs +<P></P> +</B>If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. +<P></P> +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the `copyright' line and a pointer to where the full notice is found. +<P></P> +<I>one line for the program's name and a brief idea of what it does. +<BR></I>Copyright (C) 19<I>yy</I> <I>name of author</I> +<BR> +<BR>This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. +<BR> +<BR>This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. +<BR> +<BR>You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA. +<P></P> +Also add information on how to contact you by electronic and paper mail. +<P></P> +If the program is interactive, make it output a short notice like the +following example when it starts in an interactive mode: +<P></P> +Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes +with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain +conditions; type `show c' for details. +<P></P> +The hypothetical commands <B>show w</B> and <B>show c</B> should show the appropriate parts of the General Public License. Of course, +the commands you use may be called something other than show w and show c; they can be mouse clicks or menu items—whatever suits your program. +<P></P> +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a `copyright disclaimer' for the program, if necessary. The following is a sample (when copying, alter +the names). +<P></P> +Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. +<BR> +<BR>signature of Ty Coon, 1 April 1989 +<BR>Ty Coon, President of Vice +<P></P> +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may consider +it more useful to permit linking proprietary applications with the library. If +this is what you want to do, use the GNU Library General Public License instead of this License. +<P></P> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/locals.html b/gdb/gdbtk/library/help/locals.html new file mode 100644 index 00000000000..058f94fd65f --- /dev/null +++ b/gdb/gdbtk/library/help/locals.html @@ -0,0 +1,90 @@ +<HTML> +<HEAD> +<TITLE>Locals Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Locals Window</H1> +<H2>Overview</H2> +<P>The Locals Window displays all local variables in scope. It may be used to +visualize and edit local variables.</P> + +<P>Locals Window topics: +<UL> + <LI><UL><A HREF="#menus">Variable Menu</A> + <LI><A HREF="#menus_edit">Edit</A> + <LI><A HREF="#menus_fmt">Format</A> + </UL> + <LI><UL><A HREF="#display">Locals Display</A> + <LI><A HREF="#display_deref">Dereferencing Pointers</A> + <LI><A HREF="#display_struct">Viewing a Structure or Class</A> + <LI><A HREF="#display_edit">Editing a Variable</A> + <LI><A HREF="#display_popup">Locals Pop-up Menu</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Variable Menu</A></H3> +The Variable Menu gives on-screen access to the funtions of the Locals Window. +To use any of these functions, first use the left mouse button to select a +variable from the display. Then select: + +<DL> + <DT><A NAME="menus_edit">Edit</A> + <DD>Edit the value of the variable + <DT><A NAME="menus_fmt">Format</A> + <DD>Change the display format of the variable +</DL> + +<H3><A NAME="display">Locals Display</A></H4> +The Locals Window Display consists of a scrolled listbox which contains all +local variables, one per line. To use any of the functions of the Locals Window, +use the left mouse button to select any element from the Display. + +<P>Pointers, structures, and classes appear in the display with small exapansion +box before their names. To <A NAME="display_deref">dereference pointers</A> or +<A NAME="display_struct">view the members of classes or structures</A>, click +the closed expansion box (which appears as a small plus sign, "+") to "expand" +the listing. The expansion box changes to a minus sign, "-", indicating that the +display is now open. Pointers, structures and classes may be expanded recursively +to allow multiple pointer dereferences and embedded structure viewing. + +<P>The Locals Display updates after every execution of the program and highlights +in blue those variables whose values have changed.</P> + +<P>The Locals Window will, by default, display all pointers in hexadecimal and all +other variables in decimal. To change the display format for a variable, select +the Format option from either the Variable Menu or the <A HREF="#display_popup"> +Locals Pop-up Menu</A>. +<BR> + +<H4><A NAME="display_edit">Editing a Variable</A></H4> +To edit a variable, either double-click the left mouse button on the variable in +the Display or select the Edit option from either the Variable Menu or the Locals +Pop-up Menu. To abort editing a variable's value, simply press the escape key on +the keybaord. The variable's original value is restored. +<BR> + +<H4><A NAME="display_popup">Locals Pop-up Menu</A></H4> +The Locals Pop-up Menu provides quick access to the functions of the Locals Window. +To use the Locals Pop-up Menu, first select a variable from the Display (by clicking +the left mouse button on it) and click the right mouse button, choosing from the +pop-up: +<DL> + <DT>Edit + <DD>Edit the variable's value. See <A HREF="#display_edit"> Editing a Variable + </A> + <DT>Format + <DD>Change the display format of the variable. The variable may be displayed + as: + <DL> + <DT>Hex + <DD>hexadecimal (base 16) + <DT>Decimal + <DD>decimal (base 10) + <DT>Binary + <DD>binary (base 2) + <DT>Octal + <DD>octal (base 8) + </DL> +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/memory.html b/gdb/gdbtk/library/help/memory.html new file mode 100644 index 00000000000..492974f5478 --- /dev/null +++ b/gdb/gdbtk/library/help/memory.html @@ -0,0 +1,238 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + <META NAME="GENERATOR" CONTENT="Mozilla/4.06 [en] (X11; I; Linux 2.0.35 i686) [Netscape]"> + <TITLE>Memory Window Help</TITLE> +</HEAD> +<BODY> + +<H1> +The Memory Window</H1> +The Memory Window allows users to display and edit the contents of memory. +The Memory Window Preferences controls all of the display characteristics +of the Memory Window. +<BR> +<LI> +<A HREF="#menus">Address Menu</A></LI> + +<LI> +<A HREF="#display">Memory Display</A></LI> + +<LI> +<A HREF="#prefs">Memory Window Preferences</A></LI> + +<H2> + +<HR WIDTH="100%"></H2> + +<H2> +<A NAME="menus"></A>Address Menu</H2> +<IMG SRC="images/mem_menu.gif" HEIGHT=66 WIDTH=160> +<P>This pulldown menu contains the following three items. +<DL> +<DT> +<A NAME="menus_auto"></A>Auto Update</DT> + +<DD> +When selected, causes the Memory Window to update the display every. +If it is not selected, the display will be frozen until it is selected +or "Update Now" is selected.</DD> + +<DT> +<A NAME="menus_now"></A>Update Now</DT> + +<DD> +Forces the Memory Window to update the display immediately.</DD> + +<DT> +<A NAME="menus_prefs"></A>Preferences</DT> + +<DD> +Opens the <A HREF="#prefs">Memory Window Preferences</A> dialog.</DD> +</DL> + +<H2> + +<HR WIDTH="100%"></H2> + +<H2> +<A NAME="display"></A>Memory Display</H2> +Like the <A HREF="register.html">Register Window</A>, the Memory Window +display is organized into a spreadsheet. The address of any cell in the +Display can be determined by appending the row and column headers for the +cell. Optionally, an ASCII display of the memory appears at the right. +Any non-ASCII-representable byte in memory will appear in the ASCII Display +as a control character (a dot, ".", by default). The <A HREF="#pref">Memory +Preferences Dialog</A> may be used to alter the appearance of the Memory +Window. +<P><A NAME="display_nav"></A>To navigate the Memory Window, use the mouse +and click the cell of interest. As an alternative, pressing the arrow keys +on the keyboard will focus successive cells, from left to right, top to +bottom. The focus will wrap from left to right, so hitting the right arrow +key will keep advancing the address of the cell selected. +<H4> +<A NAME="display_edit"></A>Editing Memory</H4> +To edit memory, simply enter the new value of the memory into the cell +and press the enter key on the keyboard. As with the +<A HREF="register.html">Register +Window</A>, be careful of the input format used to enter data -- the debugger +is capable of parsing binary, octal, decimal, and hexadecimal values. All +entries will be padded with leading zeroes, if necessary. After you +hit enter, the memory window will automatically shift focus to the next +cell. +<P>To edit part of the value of a cell, you can use the mouse to poistion +the cursor to the exact part of the value you want to change. You +can also use the backspace key to delete part of the value without deleting +the whole value. +<P>Another way to edit memory is to edit the ASCII window. To do +this, select a cell using the mouse. Then type in a new string. +<H4> +<A NAME="display_popup"></A>Memory Pop-up Menu</H4> +Clicking the right mouse button while the mouse cursor lies within the +bounds of any cell brings up the following menu: +<P><IMG SRC="images/mem_popup.gif" HEIGHT=100 WIDTH=220> +<DL> +<DT> +Auto Update</DT> + +<DL> +<DT> +When selected, the Memory Window will track changes in memory shown in +the Display. When not selected, the Memory Window is "frozen", representing +a "snapshot" of memory.</DT> +</DL> + +<DT> +Update Now</DT> + +<DL> +<DT> + Forces the Memory Window to update the display immediately.</DT> +</DL> + +<DT> +Go To <I>address</I></DT> + +<DD> +The Memory Window Display is updated to show memory starting at address +<I>address</I>.</DD> + +<DT> +Open New Window at <I>address</I></DT> + +<DD> +A new Memory Window is opened, displaying memory at address <I>address</I></DD> + +<DT> +Preferences...</DT> + +<DD> +Opens the Memory Window Preferences for editing the appearance of the Memory +Window Display.</DD> +</DL> + +<H2> + +<HR WIDTH="100%"></H2> + +<H2> +<A NAME="prefs"></A>Memory Window Preferences</H2> +Memory Window Preference Dialog governs the appearance of the Memory Window: +the total number of bytes displayed, the size of each cell, ASCII control +character. +<P><IMG SRC="images/mem_pref.gif" HEIGHT=417 WIDTH=330> +<H4> +<A NAME="prefs_size"></A>Size of the Display Cells</H4> +This attribute controls how many bytes appear in each cell. Valid cell +sizes in the Memory Window may be: +<DL> +<DT> +Byte</DT> + +<DD> +Each cell is exactly one byte</DD> + +<DT> +Half Word</DT> + +<DD> +Cells are displayed with two bytes</DD> + +<DT> +Word</DT> + +<DD> +Each cell contains four bytes</DD> + +<DT> +Double Word</DT> + +<DD> +Cells contain eight bytes</DD> + +<DT> +Float</DT> + +<DD> +Each cell contains four bytes, displayed as a floating point number</DD> + +<DT> +Double Float</DT> + +<DD> +Cells are displayed as floating point, eight bytes each</DD> +</DL> + +<H4> +<A NAME="prefs_fmt"></A>Format of the Display Cells</H4> +The Format option of the Memory Preferences Dialog governs how the debugger +represents the memory. Possible representations include: +<DL> +<DT> +Binary</DT> + +<DD> +The values are shown as binary numbers</DD> + +<DT> +Signed Decimal</DT> + +<DD> +The values are shown as signed decimal numbers</DD> + +<DT> +Octal</DT> + +<DD> +Each cell is represented as an octal number</DD> + +<DT> +Unsigned Decimal</DT> + +<DD> +Values are displayed as unsigned decimals</DD> + +<DT> +Hex</DT> + +<DD> +Memory is displayed as a hexadecimal number. This is the default.</DD> +</DL> + +<H4> +<A NAME="prefs_bytes"></A>Size of the Memory Window</H4> +The size of the memory window determines how much memory is actually presented +to the user. The total number of bytes shown can either be determined by +the size of the window, in which case resizing the Memory Window will cause +more or less memory to be displayed, or fixed at some specified number +of bytes. By default, the Memory Window shows 128 bytes of memory. +<H4> +<A NAME="prefs_misc"></A>Miscellaneous</H4> +Miscellaneous memory preferences include the option to display the ASCII +representation of the memory, including what character to use for non-ASCII +bytes (the "control" character). Additionally, users may specify the number +of bytes per row, either four, eight, sixteen, or thirty-two. The default +is sixteen bytes per row. +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/reg_pref.html b/gdb/gdbtk/library/help/reg_pref.html new file mode 100644 index 00000000000..b21a5747df2 --- /dev/null +++ b/gdb/gdbtk/library/help/reg_pref.html @@ -0,0 +1,20 @@ +<HTML> +<HEAD> +<TITLE>Register Window Preferences Help</TITLE> +</HEAD> +<BODY> +<H1>Register Window Preferences</H1> +<H3>Overview</H3> +<P>Not yet done.</P> + +<P>Register Window Preferences topics: +<UL> + <LI><UL><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + </UL> +</UL></P> + +<H3><A NAME="">stuff</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/register.html b/gdb/gdbtk/library/help/register.html new file mode 100644 index 00000000000..b8fff0ec187 --- /dev/null +++ b/gdb/gdbtk/library/help/register.html @@ -0,0 +1,114 @@ +<HTML> +<HEAD> +<TITLE>Register Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Register Window</H1> +<H2>Overview</H2> +<P>The Register Window lists all the registers and their contents for +the selected stack frame. It permits viewing the contents of registers +in different formats, editing register values, and some display +customizations.</P> + +<P>The Register Window will update the register contents in the display +to match the stack frame currently being viewed in the <A HREF="source.html"> +Source Window</A> and <A HREF="stack.html">Stack Winodw</A>.</P> + +<P>Register Window topics: +<UL> + <LI><UL><A HREF="#menus">Register Menu</A> + <LI><A HREF="#menus_edit">Edit</A> + <LI><A HREF="#menus_fmt">Format</A> + <LI><A HREF="#menus_remove">Remove from Display</A> + <LI><A HREF="#menus_all">Display All Registers</A> + </UL> + <LI><UL><A HREF="#display">Register Display</A> + <LI><A HREF="#display_nav">Navigating the Register Display</A> + <LI><A HREF="#display_popup">Register Pop-up Menu</A> + <LI><A HREF="#display_edit">Editing a Register</A> + <LI><A HREF="#display_format">Changing the Display Format of + a Register</A> + <LI><A HREF="#display_remove">Removing a Register + from the display</A> + <LI><A HREF="#display_all">Displaying all Registers</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Register Menu</A></H3> +The Register Menu provides on-screen access to the functionality of the +Register Window. To use any item from this menu, first use the mouse and +select (click the left mouse button) on any register cell. Users may then +select: +<BR> +<DL> + <DT><A NAME="menus_edit"><A HREF="#display_edit">Edit</A></A> + <DD>Edit the contents of the selected register + <DT><A NAME="menus_fmt"><A HREF="#display_format">Format</A></A> + <DD>Change the display format of the selected register + <DT><A NAME="menus_remove"><A HREF="#display_remove">Remove + from Display</A></A> + <DD>Remove the selected register from the Register + Window Display + <DT><A NAME="menus_all"><A HREF="#display_all">Display All + Registers</A></A> + <DD>Display all registers in the Display. This item + is only available when a register was previously + removed from the Display. +</DL> + +<H3><A NAME="display">Register Display</A></H3> +The Register Display contains name and value pairs for each register +available on the target hardware. These "cells" are layed out as a +spreadsheet for ease of use. + +<P><A NAME="display_nav"></A>To navigate the Register Display, use either +the mouse and left mouse button or the arrow keys on the keyboard to +highlight the appropriate cell. Users may then use the <A HREF="#menus"> +Register Menu</A> or use the Register Pop-up Menu to access special display +and editing options for the Register Window.</P> +<BR> + +<H4><A NAME="display_popup">The Register Pop-up Menu</A></H4> +All of the special functions of the register window are accessed through +the Register Pop-up Menu. To use the Menu, simply select a register (see +<A HREF="#display_nav">Navigating the Register Display</A>) and click the +right mouse button. The Menu offers: +<DL> + <DT><A NAME="display_edit">Edit</A> + <DD>Edit the contents of the selected register. This item + is also accessible by simply double-clicking the left + mouse button on any register in the Display. The value + of the register is set to the entered value -- the debugger + does diffferentiate between decimal, hexadecimal, octal, + and binary input. Press the escape key on the keyboard + to cancel. + <DT><A NAME="display_format">Format</A> + <DD><DL>Change the display format of the register. Valid display types + are: + <DT>Hex + <DD>The register's contents are displayed in + hexadecimal (base 16). + <DT>Decimal + <DD>The value is shown as + a decimal number (base 10). + <DT>Natural + <DD>The register is displayed in its natural format. + <DT>Binary + <DD>The contents of the register are displayed + as a binary number (base 2). + <DT>Octal + <DD>The register's contents are shown in octal (base 8). + <DT>Raw + <DD>The raw contents of the register are shown. + </DL> + <DT><A NAME="display_remove">Remove</A> + <DD>Remove the selected register from the display. To display + the removed register again, select the "Display All Registers" + option from the Register Menu or the Register Pop-up Menu. + <DT><A NAME="display_all">Display All Registers</A> + <DD>Causes the Register Window Display to show all registers, + including those which were previously "removed". This menu + item is only available when removed registers exist. +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/source.html b/gdb/gdbtk/library/help/source.html new file mode 100644 index 00000000000..c37091a9460 --- /dev/null +++ b/gdb/gdbtk/library/help/source.html @@ -0,0 +1,416 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + <META NAME="GENERATOR" CONTENT="Mozilla/4.06 [en] (X11; I; Linux 2.0.35 i686) [Netscape]"> + <TITLE>Source Window Help</TITLE> +</HEAD> +<BODY> + +<CENTER> +<H1>The Source Window</H1></CENTER> + +<BR>The Source Window is the primary interface between the user and +the debugger; it is automatically opened when the debugger starts. The +Source Window displays the status of the program, controls execution of +the program, and allows visualization of the program execution. + +<H3><A HREF="#menus">Menus</A></H3> + +<UL> +<LI><A HREF="#menus_file">File Menu</A></LI> +<LI><A HREF="#menus_run">Run Menu</A></LI> +<LI><A HREF="#menus_view">View Menu</A></LI> +<LI><A HREF="#menus_control">Control Menu</A></LI> +<LI><A HREF="#menus_prefs">Preferences Menu</A></LI> +</UL> + +<H3><A HREF="#toolbar">Toolbar</A></H3> + +<UL> +<LI><A HREF="#toolbar_exec">Execution Control Buttons</A></LI> +<LI><A HREF="#toolbar_window">Window Buttons</A></LI> +<LI><A HREF="#toolbar_frame">Frame Control</A></LI> +</UL> + +<H3><A HREF="#display">Source Window Display</A></H3> + +<UL> +<LI><A HREF="#setting_a_breakpoint">Setting a Breakpoint</A></LI> +<LI><A HREF="#viewing_breakpoints">Viewing Breakpoints</A></LI> +<LI><A HREF="#display_balloon">Variable Balloons</A></LI> +<LI><A HREF="#display_popup">Source Pop-up Menus</A></LI> +</UL> + +<H3><A HREF="#status">Source Window Status Bars</A></H3> + +<UL> +<LI><A HREF="#status_bar">Program Status Bar</A></LI> +<LI><A HREF="#status_mode">Source Display Status Bar</A></LI> +</UL> + +<H3><A HREF="#search">Search Entry</A></H3> + +<HR> +<H2><A NAME="menus"></A>Menus</H2> + +<IMG SRC="images/src_menu.gif"> +<H4><A NAME="menus_file"></A>File Menu</H4> + +<DL> +<DT>Open</DT> +<DD>Opens a file selection dialog to select the executable to debug</DD> +<DT>Target Settings...</DT> +<DD>Opens the <A HREF="target.html">Target Selection Dialog</A> to edit target +settings</DD> +<DT>Page Setup</DT> +<DD>(Windows only) Opens the Windows Page Setup dialog to configure printing</DD> +<DT>Print</DT> +<DD>(Windows only) Print the contents of the Source Window Display</DD> +<DT>Exit</DT> +<DD>Exits the debugger</DD> +</DL> + +<H4><A NAME="menus_run"></A>Run Menu</H4> +<DL> +<DT>Download</DT> +<DD>Initiates download of the executable onto the target via the protocol specified +in the <A HREF="target.html">Target Selection Dialog</A></DD> +<DT>Run</DT> +<DD>Runs or re-runs the program</DD> +</DL> + +<H4><A NAME="menus_view"></A>View Menu</H4> +<DL> +<DT>Stack</DT> +<DD>Open a <A HREF="stack.html">Stack Window</A></DD> +<DT>Registers</DT> +<DD>Open a <A HREF="register.html">Register Window</A></DD> +<DT>Memory</DT> +<DD>Open a <A HREF="memory.html">Memory Window</A></DD> +<DT>Watch Expressions</DT> +<DD>Open a <A HREF="watch.html">Watch Window</A></DD> +<DT>Local Variables</DT> +<DD>Open a <A HREF="locals.html">Locals Window</A></DD> +<DT>Breakpoints</DT> +<DD>Open a <A HREF="breakpoint.html">Breakpoint Window</A></DD> +<DT>Console</DT> +<DD>Open a <A HREF="console.html">Console Window</A></DD> +<DT>Function Browser</DT> +<DD>Open a window allowing the user to easily search for functions and +set breakpoints.</DD> +<DT>Thread List</DT> +<DD>Open a window that displays all current threads and allows the user +to change active threads</DD> +</DL> + +<H4><A NAME="menus_control"></A>Control Menu</H4> +<DL> +<DT><A HREF="#step_button">Step</A></DT> +<DD>Step program until it reaches a different source line</DD> +<DT><A HREF="#next_button">Next</A></DT> +<DD>Step program, proceeding through subroutine calls</DD> +<DT><A HREF="#finish_button">Finish</A></DT> +<DD>Execute until the current stack frame returns</DD> +<DT><A HREF="#continue_button">Continue</A></DT> +<DD>Continue program being debugged, after signal or breakpoint</DD> +<DT><A HREF="#stepi_button">Step Asm Inst</A></DT> +<DD>Step one instruction exactly</DD> +<DT><A HREF="#nexti_button">Next Asm Inst</A></DT> +<DD>Step one instruction, but proceed through subroutine calls</DD> +<DT>Automatic Step</DT> +<DD>Automatically step the program every two seconds</DD> +</DL> + +<H4><A NAME="menus_prefs"></A>Preferences Menu</H4> +<DL> +<DT>Global</DT> +<DD>Opens the <A HREF="gbl_pref.html">Global Preferences Dialog</A> and allows +editing of global settings</DD> +<DT>Source</DT> +<DD>Opens the <A HREF="src_pref.html">Source Preferences Dialog</A> and allows +editing of Source Window settings</DD> +</DL> + +<HR> + +<H2><A NAME="toolbar"></A>Toolbar</H2> +<IMG SRC="images/src_toolbar.gif"> +The Source Window toolbar consists of three functional sections: execution +control buttons, debugger window buttons, and stack frame control buttons. + +<BR> +<H4><A NAME="toolbar_exec"></A>Execution Control Buttons</H4> +These convenience buttons provide on-screen access to the most important +debugger execution control functions: +<DL> +<DT><A NAME="run_button"></A><IMG SRC="../images/run.gif"> or +<IMG SRC="../images2/run.gif"> Run </DT> +<DD>The Run Button will start execution of the program, including target selection +and downloading, if necessary. If the program is already running, the Run +Button will start the program from the beginning (re-run it).</DD> + +<DT><A NAME="stop_button"></A><IMG SRC="../images/stop.gif"> or +<IMG SRC="../images2/stop.gif"> Stop</DT> +<DD>The Stop Button will interrupt execution of the program (provided this +feature is supported by the underlying debugging protocol and hardware) +or cancel downloads. It is also used as an indication that the debugger +is busy.</DD> +<DT><A NAME="step_button"></A><IMG SRC="../images/step.gif"> or <IMG SRC="../images2/step.gif">Step</DT> +<DD>Step the program until it reaches a different source line</DD> +<DT><A NAME="next_button"></A><IMG SRC="../images/next.gif"> or <IMG SRC="../images2/next.gif">Next</DT> +<DD>Step the program, proceeding through subroutine calls</DD> +<DT><A NAME="finish_button"></A><IMG SRC="../images/finish.gif"> or <IMG SRC="../images2/finish.gif"> Finish</DT> +<DD>Execute until the current stack frame returns</DD> +<DT><A NAME="continue_button"></A><IMG SRC="../images/continue.gif"> or <IMG SRC="../images2/continue.gif"> Continue</DT> +<DD>Continue the program being debugged, after signal or breakpoint</DD> +<DT><A NAME="stepi_button"></A><IMG SRC="../images/stepi.gif"> or <IMG SRC="../images2/stepi.gif"> Step Asm Inst</DT> +<DD>Step one instruction exactly. This function is only available when the +Source Window is displaying assembler code.</DD> +<DT><A NAME="nexti_button"></A><IMG SRC="../images/nexti.gif"> or <IMG SRC="../images2/nexti.gif"> Next Asm Inst</DT> +<DD>Step one instruction, but proceed through subroutine calls. This function +is only available when the Source Window is displaying assembler code.</DD> +</DL> + +<H4> +<A NAME="toolbar_window"></A>Window Buttons</H4> +The Debugger Window buttons give instant access to the Debugger's auxiliary +windows: +<DL> +<DT><A NAME="register_button"></A><IMG SRC="../images/reg.gif"> or <IMG SRC="../images2/reg.gif"> Registers</DT> +<DD>Open a <A HREF="register.html">Register Window</A></DD> +<DT><A NAME="memory_button"></A><IMG SRC="../images/memory.gif"> or <IMG SRC="../images2/memory.gif"> Memory</DT> +<DD>Open a <A HREF="memory.html">Memory Window</A></DD> +<DT><A NAME="stack_button"></A><IMG SRC="../images/stack.gif"> or <IMG SRC="../images2/stack.gif"> Stack</DT> +<DD>Open a <A HREF="stack.html">Stack Window</A></DD> +<DT><A NAME="watch_button"></A><IMG SRC="../images/watch.gif"> or <IMG SRC="../images2/watch.gif"> Watch Expressions</DT> +<DD>Open a <A HREF="watch.html">Watch Window</A></DD> +<DT><A NAME="locals_button"></A><IMG SRC="../images/vars.gif"> or <IMG SRC="../images2/vars.gif"> Local Variables</DT> +<DD>Open a <A HREF="locals.html">Locals Window</A></DD> +<DT><A NAME="breakpoints_button"></A><IMG SRC="../images/bp.gif"> or <IMG SRC="../images2/bp.gif"> Breakpoints</DT> +<DD>Open a <A HREF="breakpoint.html">Breakpoint Window</A></DD> +<DT><A NAME="console_button"></A><IMG SRC="../images/console.gif"> or <IMG SRC="../images2/console.gif"> Console</DT> +<DD>Open a <A HREF="console.html">Console Window</A></DD> +</DL> + +<H4><A NAME="toolbar_frame"></A>Frame Control</H4> +The Frame Control area of the toolbar displays information about the PC +of the current frame, and the frame control buttons may be used to navigate +through the call stack. Whenever any of these buttons are used, both the +Source Window Display and the <A HREF="stack.html">Stack Window</A> will +show the selected frame. +<DL> +<DT><IMG SRC="images/frame_info.gif" > Frame Information Display</DT> +<DD>The left half of the frame information display shows the value of the PC +in the current frame. The right half shows the line number of the PC in +the source file, if available.</DD> + +<DT><A NAME="up_button"></A><IMG SRC="../images/up.gif"> or <IMG SRC="../images2/up.gif"> Up</DT> +<DD>Select and view the stack frame that called this one</DD> + +<DT><A NAME="down_button"></A><IMG SRC="../images/down.gif"> or <IMG SRC="../images2/down.gif"> Down</DT> +<DD>Select and view the stack frame called by this one</DD> + +<DT><A NAME="bottom_button"></A><IMG SRC="../images/bottom.gif"> or <IMG SRC="../images2/bottom.gif"> Bottom</DT> +<DD>Select and view the bottom-most stack frame</DD> +</DL> + +<HR> + +<H2><A NAME="display"></A>Source Display</H2> +The Source Display is used for many things: browsing source code, setting +and clearing breakpoints, and a few other special functions. Executable +lines (those for which executable code was generated by the compiler) are +denoted with a marker (a dash, "-") in the first column of the display. +<P>The debugger highlights the PC in the current frame in either green, +indicating that the PC is in the bottom-most frame (i.e., it is being executed) +or gold, indicating that the PC is contained in a frame that is not currently +executing (because it has called another function). A blue highlight is +used by the debugger to indicate a browsing position: the PC is contained +in a frame that is not executing or on the call stack. All highlight colors +are user selectable in the <A HREF="src_pref.html">Source Preferences</A>. + +<BR> +<H4><A NAME="setting_a_breakpoint"></A>Setting a Breakpoint</H4> +Moving the mouse pointer over the "hot spot" of an executable line will +change the mouse cursor to a large dot. Clicking the left mouse button +will then toggle a breakpoint at this line. If no breakpoint exists, one +will be installed and the dash in the left margin will change into a red +breakdot. If a breakpoint exists, it will be removed and the red breakdot +will revert back to a dash. The executable line marker shows the status +of each line: an empty marker (the dash) indicates that no breakpoints +are set at the line. A colored breakdot indicates that a breakpoint exists +at the line (see <A HREF="#display_popup">Source Pop-up Menus</A> for more +information on setting different types of breakpoints and their representations +in the Source Display). +<P>Black breakdots in the Source Window display indicate that the breakpoint +has been disabled. To re-enable the breakpoint, click the enable/disable +checkbox in the Breakpoint Window (see <A HREF="breakpoint.html#display_state"> +Enabling/Disabling Breakpoints</A>). + +<BR> +<H4><A NAME="viewing_breakpoints"></A>Viewing Breakpoints</H4> +You can find out more information about a breakpoint by moving the cursor +over a breakpoint. A balloon window will pop up with additional information. +To get a list of all the active breakpoints, you will need to open a +<A HREF="breakpoint.html">breakpoint window</A>. +<IMG SRC="images/src_bp_bal.gif"> + +<BR> +<H4><A NAME="display_balloon"></A>Variable Balloons</H4> +If the program to be debugged has started and is stopped, the display +will show the value of variables in variable +balloons. To activate a variable balloon, simply hold the mouse cursor +over the name of a variable in the Source Display for a second or two: +the debugger displays the name of the variable, its type, and its value +in a pop-up balloon. +<IMG SRC="images/src_bal.gif"> + +<BR> +<H4><A NAME="display_popup"></A>Source Pop-up Menus</H4> +The Source Display has two pop-up menus. One is activated by clicking the +right mouse button when the mouse cursor is over an executable line marker's +hot spot. This pop-up menu looks like this: +<P><IMG SRC="images/src_bpop.gif"> +<DL> +<DT>Continue to Here</DT> +<DD>Continue program execution until it reaches this point. All breakpoints +will be ignored. Be aware that if the program never executes the line you selected, +it will run until completion.</DD> +<DT>Set Breakpoint</DT> +<DD>Set a breakpoint at this line. This has the same effect as left clicking +on this line. Breakpoints are shown as red breakdots in the Source Window +Display.</DD> +<DT>Set Temporary Breakpoint</DT> +<DD>Set a temporary breakpoint at this line. Temporary breakpoints are shown +as orange breakdots in the Source Window Display. The remove themselves automatically +the first time they are hit.</DD> +<A NAME="thread_bp"></A> +<DT>Set Breakpoint on Thread(s)...</DT> +<DD>GDB allows the user to set a breakpoint on a particular thread or threads. This +menu item will display a dialog with a list of threads. The user can select a list +of threads that will have breakpoints set at the selected line number. A warning +will be displayed if there are no active threads.</DD> +<IMG SRC="images/src_thread.gif"> +</DL> + +The other pop-up menu is activated by clicking the right mouse button anywhere +else in the Source Display. It is only available when a variable or number +in the display lies below the mouse cursor or is selected (by clicking +the left mouse button and dragging the mouse to highlight the variable/number). +The pop-up menu looks like this: +<P><IMG SRC="images/src_pop.gif"> +<DL> +<DT><A NAME="add_to_watch"></A>Add <I>expr</I> to Watch</DT> +<DD>Adds the selected expression to the <A HREF="watch.html">Watch Window</A>, +opening it, if necessary.</DD> +<DT>Dump Memory at <I>expr</I></DT> +<DD>Opens a new <A HREF="memory.html">Memory Window</A> at the selected expression. +If the expression is a variable, then the Memory Window is opened with +memory addresses starting at the value of the variable.</DD> +<DT>Open Another SOurce Window</DT> +<DD>GDB allows multiple source windows to co-exist. You can, for example, have +one window in source mode and one in assembly mode. Or you can use one window +to browse the stack or other files.</DD> +</DL> + +<H4><A NAME="status"></A>Source Window Status Bars</H4> +The Source Window has two status bars which inform the user of the status +of the program (the "status bar") and the status of the Source Window. +<P>The <A NAME="status_bar"></A>Program Status Bar (or simply "Status +Bar") displays the status of the program. Common messages seen here include: +<DL> +<DT>No program loaded.</DT> +<DD>No program has been loaded into target memory.</DD> +<DT>Program is ready to run.</DT> +<DD>A program has been loaded into target memory and may be executed. Start +the program by hitting <A HREF="#run_button">Run</A>.</DD> +<DT>Program stopped at <I>line/address</I></DT> +<DD>The program stopped at line <I>line</I> or address <I>address</I>. Execution +may continue by hitting any of the <A HREF="#toolbar_exec">execution control +buttons</A> on the toolbar.</DD> +<DT>Program terminated. 'Run' will restart.</DT> +<DD>The program exited. Pressing <A HREF="#run_button">Run</A> will restart +it.</DD> +</DL> + +The Status Bar also displays some help information. For instance, the Status +Bar will show the function of a button on the toolbar or the Source Display +Status Bar as well as any keyboard shortcut for any button in the Source +Window. + +<BR> +<H4><A NAME="status_mode"></A>Source Display Status Bar</H4> +<IMG SRC="images/src_stat.gif"> +The Source Display Status Bar shows the current state of the Source Window: +the name of the file displayed in the Display, the name of the function +in the Display which contains the PC for the current frame (if any), and +the display mode. +<P>The <A NAME="file_selector"></A>Source File Selector is a dropdown +menu which contains the names of all the files that were compiled into +the program being debugged. +<P>Normally, the File Selector displays the name of the file currently +being viewed, but any file from the dropdown menu may be selected for browsing. +Simply select the file to view from the available choices (or type it directly +into the File Selector) and the Source Window will load that file into +the Display. To return to the PC of the program, simply press the +<A HREF="#bottom_button">Bottom +Frame Control Button</A>. +<P>The <A NAME="function_selector"></A>Source Function Selector displays +the name of the function containing the Source Window's PC, if one exists, +but it may be used to browse any function in the current file. Simply type +the name of the desired function into the Function Selector or select it +from the dropdown menu. The Source Window's PC is updated to point at this +function. To return to the PC of the program, simply press the +<A HREF="#bottom_button">Bottom +Frame Control Button</A>. +<P>The <A NAME="mode_selector"></A>Source Display Mode Selector displays +the viewing mode of the current file/function shown in the Source Window +Display. +<P>The function of the "step" keyboard shortcut will differ depending on +the mode the Source Window Display. "Stepping" in Source Mode (or in the +Source Pane of SRC+ASM Mode) will cause a source-level step. "Stepping" +in Assembly or Mixed Mode (or in the Assembly Pane of the SRC+ASM Mode) +will cause the debugger to step exactly one machine instruction. This also +applies to the shortcut for "next". +<P>The Display Mode Selector may be used to change the view of the current +source file. The available display modes are +<DL> +<DT>SOURCE</DT> +<DD>The contents of the Display are shown as source code. If source code is +not available (either because no debugging information is available or +the source file is not found), the Source Window will temporarily set the Display +Mode to "ASSEMBLY".</DD> +<DT>ASSEMBLY</DT> +<DD>A disassembly of the target's memory is shown in the Display. Even assembly +source files show a disassembly of target memory; to see the assembly source +code, use the SOURCE mode. Note that the debugger can only display assembly +code on a function-by-function basis. It cannot display all the instructions +generated from a single source file.</DD> +<DT>MIXED</DT> +<DD>The Display shows source code mixed with the assembler instructions which +were generated for those lines by the compiler for the current function. +Note that the addresses of the assembly lines is not necessarily monotonically +increasing. If the source file associated with the function cannot be found, +the Source Window will revert to ASSEMBLY mode.</DD> +<DT>SRC+ASM</DT> +<DD>The Source Window Display is divided into two panes: an assembly pane and +a source pane. Breakpoints may be set/cleared in either pane.</DD> +</DL> + +<HR> + +<H2><A NAME="search"></A>Search Entry</H2> +The Search Entry facilitates searching for text in the Source Window Display. +Simply enter the text to be found into the Search Entry and press the Enter +key on the keyboard to search forwards in the Source Window Display (hold +down the Shift key to search backwards). If a match is found, it is highlighted +in the Source Window and the Program Status Bar displays information about +where the match was found. +<P>The Search Entry can also jump the Source Window to a specific line. +Enter the line number preceded by an "at" sign (@) into the Search Entry +and press enter. If entered line number is greater than the total number +of lines in the Source Window Display, the Display will jump to the end +of the current file. +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/src_pref.html b/gdb/gdbtk/library/help/src_pref.html new file mode 100644 index 00000000000..e8547964653 --- /dev/null +++ b/gdb/gdbtk/library/help/src_pref.html @@ -0,0 +1,20 @@ +<HTML> +<HEAD> +<TITLE>Source Window Preferences Help</TITLE> +</HEAD> +<BODY> +<H1>Source Window Preferences</H1> +<H3>Overview</H3> +<P>Not yet done.</P> + +<P>Source Preferences topics: +<UL> + <LI><UL><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + </UL> +</UL></P> + +<H3><A NAME="">stuff</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/stack.html b/gdb/gdbtk/library/help/stack.html new file mode 100644 index 00000000000..9229c17fa12 --- /dev/null +++ b/gdb/gdbtk/library/help/stack.html @@ -0,0 +1,50 @@ +<HTML> + <HEAD> + <TITLE>Stack Window Help</TITLE> + </HEAD> + <BODY> + + <CENTER> + <H2>The Stack Window</H2> + </CENTER> + + + <BR>The Stack Window allows users to view the call stack and jump between + levels of the stack. + + <UL> + <LI><A HREF="#display">Stack Display</A></LI> + <LI><A HREF="#display_nav">Navigating the Stack Window</A></LI> + <LI><A HREF="#display_lvl">Changing the Stack Level</A></LI> + </UL> + + <H2><A NAME="display">Stack Display</A></H2> + The Stack Display consists of a listbox which displays levels of the call stack + on per line. Each line contains the level number (useful when using the + <A HREF="console.html">Console Window</A>) and a description of the function executing + in that level. Typically, the function name and either the address of the function + or the file and line number where the function is defined are displayed. The + Stack Window may also be used to jump between levels of the stack. + <BR> + + <H2><A NAME="display_nav">Navigating the Stack Window</A></H2> + Navigation of the Stack Window is accomplished by clicking on the desired level + with the left mouse button. The <A HREF="source.html#display">Source Window + Display</A> updates to show the selected frame. All other secondary windows, + <A HREF="register.html">Registers</A>, <A HREF="watch.html">Watch</A>, and + <A HREF="locals.html">Locals</A> update their displays for the selected frame. + <BR> + + <H2><A NAME="display_lvl">Changing Stack Levels</A></H2> + To switch frames, simply click the left mouse button on the desired frame and the + debugger will switch contexts, updating all windows. The selected frame is highlighted + (in gold, by default). + + <P>As an alternative, changing stack levels may be accomplished via the + <A HREF="source.html#toolbar_frame">Frame Control Buttons</A> on the Source Window's + Toolbar. These buttons may be used to change frames one level at a time (either + immediately up or immediately down) or to jump to the bottom-most stack frame. + See <A HREF="source.html#toolbar_frame">Source Frame Control Buttons</A> for more + information.</P> + </BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/target.html b/gdb/gdbtk/library/help/target.html new file mode 100644 index 00000000000..2f81fb6720e --- /dev/null +++ b/gdb/gdbtk/library/help/target.html @@ -0,0 +1,99 @@ +<HTML> +<HEAD> +<TITLE>Target Selection Help</TITLE> +</HEAD> +<BODY> +<H1>The Target Selection Dialog</H1> +<H3>Overview</H3> +<P>The Target Selection Dialog allows users to specify the debug target, +the interface used to connect to the target, and some useful run +options.</P> + +<P>Target Selection topics: +<UL> + <LI><UL><A HREF="#select">Selecting a Target</A> + <LI><A HREF="#select_tar">Specifying a Target</A> + <LI><A HREF="#select_int">Choosing a Connection Interface</A> + </UL> + <LI><UL><A HREF="#options">Options</A> + <LI><A HREF="#options_run_until_main">Run until 'main'</A> + <LI><A HREF="#options_bp_at_exit">Set breakpoint at 'exit'</A> + <LI><A HREF="#options_download_dialog">Display Download Dialog</A> + </UL> + <LI><UL><A HREF="#more_options">More Options</A> + <LI><A HREF="#more_options_attach">Attach to Target</A> + <LI><A HREF="#more_options_load">Download Program</A> + <LI><A HREF="#more_options_run">Run Program</A> + <LI><A HREF="#more_options_cont">Continue from Last Stop</A> + </UL> +</UL></P> + +<H3><A NAME="select">Selecting a Target</A></H3> +Selecting a target involves choosing a target for debugging and setting connection +interface options for the target. + +<P>Common targets include: "Exec" for native debuggers, "Remote/Serial" for establishing +a connection to a target board via a serial line, "Remote/TCP" for TCP connections, +and "Simulator" for connections to the simulator. There may be more depending on the +configuration of the debugger being used.</P> + +<P>In general, "remote" targets are always serial connections which require the user +to specify the serial port and baud rate to be used for the connection and +"remote/tcp" targets are always TCP connections which require specifying the hostname +and port number of the machine to which to connect. Depending upon configuration, +there may be numerous serial- and TCP-based connections. These always follow the +naming convention <I>target</I>/Serial and <I>target</I>/TCP.</P> + +<P>To <A NAME="select_tar"> select a target</A>, choose one of the available targets +from the dropdown menu in the Connection Frame. Then <A NAME="#select_int">specify +the interface options</A> for this target: selecting the baudrate and serial port +from the dropdown menus (serial targets only) or entering the hostname and port number +(TCP targets only).</P> + +<H3><A NAME="options">Options</A></H3> +Three run options which may be selected include: +<DL> + <DT><A NAME="options_run_until_main">Run until 'main' + <DD>Sets a breakpoint at main() + <DT><A NAME="options_bp_at_exit">Set breakpoint at 'exit' + <DD>Sets a breakpoint at exit() + <DT><A NAME="options_download_dialog">Display Download Dialog + <DD>Displays a dialog showing the progress of the download to + the target section by section +</DL> +<BR> +<H3><A NAME="more_options">More Options</A></H3> +Several additional run options may be set for each target from the Target Selection +Dialog. These options govern the behavior of the debugger's +<A NAME="source.html#run_button">Run Button</A>. The debugger automatically selects +default values for these options whenever a target is selected with the dropdown menu +in the Connection Frame. To modify this default bahavior, click the small triangle +next to "More Options" at the bottom of the dialog. The Run Options for the current +target are displayed, allowing modification of the actions for the target. When the +"OK" button is selected, these settings are saved and will be used as the default +for the target in future sessions. + +<DL> + <DT><A NAME="more_options_attach">Attach to Target</A> + <DD>Establish a connection to the target board. + <DT><A NAME="more_options_load">Download Program</A> + <DD>Download the program to the target board. + <DT><A NAME="more_options_run">Run Program</A> + <DD>Run the program on the target board, creating a new + "process". This option may not be specified along with + the continue option. See note below. + <DT><A NAME="more_options_cont">Continue from Last Stop</A> + <DD>Continue the program on the target board from where + it last stopped. This option may not be specified + along with the "run" option. See note below. +</DL> + +<P>Note that all remote targets typically do not "run" programs. Since target +boards are usually incapable of creating a new "process", these targets +seldom "Run". The defaults for all remote targets reflect this distinction: they +are all set to "Continue".</P> + +<P>Only one of the options "Run Program" and "Continue from Last Stop" may be used. +Typically, the default behavior of this setting should not be altered.</P> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/thread.html b/gdb/gdbtk/library/help/thread.html new file mode 100644 index 00000000000..dacc0646125 --- /dev/null +++ b/gdb/gdbtk/library/help/thread.html @@ -0,0 +1,46 @@ +<HTML> + <HEAD> + <TITLE>Thread Window Help</TITLE> + </HEAD> + <BODY> + + <CENTER> + <H2>The Thread Window</H2> + </CENTER> + + + <BR>The Thread Window displays a list of threads and/or processes. The exact + contents are OS-specific. + + <UL> + <LI><A HREF="#display">Thread Display</A></LI> + <LI><A HREF="#current">Changing the Current Thread</A></LI> + <LI><A HREF="#bp">Setting Breakpoints on Thread(s)</A></LI> + </UL> + + <H2><A NAME="display">Thread Display</A></H2> + The Thread Display consists of a listbox which displays information on + threads and/or processes that are part of the executable being debugged. + The first column is the GDB thread number, which is used internally by GDB + to track the thread. The rest of the columns are OS-dependent. The output is identical + to the output of the console command "info threads". + <BR> + + <H2><A NAME="current">Changing the Current Thread</A></H2> + The source window can only display the current location and source for one thread + at a time. That thread is called the "current thread". + To change the current thread, simply click the left mouse button on the desired + line and the + debugger will switch contexts, updating all windows. The current thread will + be highlighted. + <BR> + + <H2><A NAME="bp">Setting Breakpoints on Thread(s)</A></H2> + Normally if you set a breakpoint on a line or function, every thread that hits + that location will stop execution and return to the debugger. To set a breakpoint + or a specific thread or threads, you need to use the source window. See + <A HREF="source.html#thread_bp">Set Breakpoint on Threads</A> + + + </BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/console.html b/gdb/gdbtk/library/help/trace/console.html new file mode 100644 index 00000000000..fdce956afec --- /dev/null +++ b/gdb/gdbtk/library/help/trace/console.html @@ -0,0 +1,47 @@ +<HTML> +<HEAD> +<TITLE>Console Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Console Window</H1> +<H3>Overview</H3> +<P>The Console Window is perhaps the most powerful tool in the debugger. It +provides functionality equivalent to almost all of the debugger's secondary +windows, macro definitions, and other more advanced features.</P> + +<P>Console Window topics: +<UL> + <LI><UL><A HREF="#display">Console Display</A> + <LI><A HREF="#display_cmd">Executing Commands</A> + <LI><A HREF="#display_hlp">Getting Help</A> + </UL> +</UL></P> + +<H3><A NAME="display">Console Display</A></H3> +The Console Display is simply a scrolled window in which the debugger prompt +appears. By default, the prompt is set to "(gdb) ", but it may be changed via a +command line option. + +<P>To <A NAME="display_cmd">execute commands</A> in the console window, simply enter +the command in the display. If the debugger is busy, the message "Error: The +debugger is busy." appears informing the user that the command was not accepted.</P> + +<P>Whenever a command is executed, the debugger's windows will update to display +any new state information. Any output from the command is also echoed to the Console +Window for ease of use. If an error occurs, an error message is printed to the Console +Window. All error messages appear in the Console Window using a red colored typeface. +</P> + +<P>The Console Window responds to special character commands just as a shell window +does: it has a history mechanism which allows the user to scan previously used commands +by pressing the up and down arrow keys on the keyboard, jumping to the beginning or +end of a line by entering Ctrl-A or Ctrl-E, erasing a line by pressing Ctrl-K, and +more. Users familiar with GNU Emacs will recognize these keys as commonly used +keystrokes from that editor.</P> + +<H3><A NAME="display_hlp">Getting Help</A></H3> +The Console Window has its own online help system. To access the help system, enter +"help" at the prompt and follow the on-screen instructions. For more help, please +consult the <!-- What is this really called? --> <I>GDB User's Guide</I>. +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/gbl_pref.html b/gdb/gdbtk/library/help/trace/gbl_pref.html new file mode 100644 index 00000000000..2760750c4e9 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/gbl_pref.html @@ -0,0 +1,20 @@ +<HTML> +<HEAD> +<TITLE>Global Preferences Help</TITLE> +</HEAD> +<BODY> +<H1>Global Preferences</H1> +<H3>Overview</H3> +<P>Not yet done.</P> + +<P>Global Preferences topics: +<UL> + <LI><UL><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + </UL> +</UL></P> + +<H3><A NAME="">stuff</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/help.html b/gdb/gdbtk/library/help/trace/help.html new file mode 100644 index 00000000000..3a3640da1a1 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/help.html @@ -0,0 +1,32 @@ +<HTML> +<HEAD> +<TITLE>Help Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Help Window</H1> +<H2>Overview</H2> +<P>This is some nice text which describes the help window, its role +in deugging, and perhaps some of the nifty things people can do with +this window.</P> + +<P>Help Window topics: +<UL> + <LI><UL><A HREF="#menus">Menus</A> + <LI><A HREF="#menus_file">File Menu</A> + <LI><A HREF="#menus_topics">Topics Menu</A> + </UL> + <LI><UL><A HREF="#display">Help Display</A> + <LI><A HREF="#display_nav">Navigating the Help Window</A> + <LI><A HREF="#display_link">Definition and Page Links</A> + </UL> +</UL></P> + +<H2><A NAME="menus">Menus</A></H2> +<H3><A NAME="menus_file">File Menu</A></H3> +<H3><A NAME="menus_topics">Topics Menu</A></H3> + +<H3><A NAME="display">Help Display</A></H3> +<H3><A NAME="display_nav">Navigating the Help Window</A></H3> +<H3><A NAME="display_link">Definition and Page Links</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/index.toc b/gdb/gdbtk/library/help/trace/index.toc new file mode 100644 index 00000000000..3559d66350e --- /dev/null +++ b/gdb/gdbtk/library/help/trace/index.toc @@ -0,0 +1,10 @@ +{Source Window} {source.html} {The Source Window} +{Register Window} {register.html} {The Register Window} +{Memory Window} {memory.html} {The Memory Window} +{Locals Window} {locals.html} {The Locals Window} +{Watch Window} {watch.html} {The Watch Window} +{Tracepoint Window} {tp.html} {The Tracepoint Window} +{Console Window} {console.html} {The Console Window} +{Stack Window} {stack.html} {The Stack Window} +{TDump Window} {tdump.html} {The Tracepoint Dump Window} +{GPL} {license.html} {The GNU Public License} diff --git a/gdb/gdbtk/library/help/trace/license.html b/gdb/gdbtk/library/help/trace/license.html new file mode 100644 index 00000000000..b43da4cb3a4 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/license.html @@ -0,0 +1,305 @@ +<HTML> +<HEAD> +<TITLE>GNU General Public License</TITLE> +</HEAD><BODY> +<B>The GNU General Public License +<P></P> +</B>Version 2, June 1991 +<P></P> +Copyright © 1989, 1991 Free Software Foundation, Inc. +<BR>59 Temple Place / Suite 330, Boston, MA 02111-1307, USA +<P></P> +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. +<P></P> +<B>Preamble +<P></P> +</B>The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and +change free software to make sure the software is free for all its users. This General Public +License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some +other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, +too. +<P></P> +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change the +software or use pieces of it in new free programs; and that you know you can +do these things. +<P></P> +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. +<P></P> +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must show +them these terms so they know their rights. +<P></P> +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute and/or +modify the software. +<P></P> +Also, for each author's protection and ours, we want to make certain that everyone understands that +there is no warranty for this free software. If the software is modified by +someone else and passed on, we want its recipients to know that what they have is +not the original, so that any problems introduced by others will not reflect on +the original authors' reputations. +<P></P> +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for +copying, distribution and modification follow. +<P></P> +<B>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +<P></P> +</B>0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of this +General Public License. The `Program”, below, refers to any such program or work, and a `work based on the Program' means either the Program or any derivative work under copyright law: that is +to say, a work containing the Program or a portion of it, either verbatim or +with modifications and/or translated into another language. (Hereinafter, +translation is included without limitation in the term `modification'.) Each licensee is addressed as `you'. +<P></P> +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. +<P></P> +<OL><LI> You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the Program +a copy of this License along with the Program. +<P></P> +</OL>You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. +<P></P> +<OL START="2"><LI> You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: +<P></P> +</OL>a) You must cause the modified files to carry prominent notices stating that you +changed the files and the date of any change. +<P></P> +b) You must cause any work that you distribute or publish, that in whole or in +part contains or is derived from the Program or any part thereof, to be licensed +as a whole at no charge to all third parties under the terms of this License. +<P></P> +c) If the modified program normally reads commands interactively when run, you +must cause it, when started running for such interactive use in the most ordinary +way, to print or display an announcement including an appropriate copyright +notice and a notice that there is no warranty (or else, saying that you provide a +warranty) and that users may redistribute the program under these conditions, +and telling the user how to view a copy of this License. (Exception: if the +Program itself is interactive but does not normally print such an announcement, +your work based on the Program is not required to print an announcement.) +<P></P> +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and its +terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a work +based on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the entire whole, +and thus to each and every part regardless of who wrote it. +<P></P> +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on the +Program. +<P></P> +In addition, mere aggregation of another work not based on the Program with +the Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this License. +<P></P> +<OL START="3"><LI> You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: +<P></P> +</OL>a) Accompany it with the complete corresponding machine-readable source code, +which must be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, +<P></P> +b) Accompany it with a written offer, valid for at least three years, to give any +third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding source +code, to be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, +<P></P> +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for noncommercial +distribution and only if you received the program in object code or executable +form with such an offer, in accord with Subsection b above.) +<P></P> +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all the +source code for all modules it contains, plus any associated interface definition +files, plus the scripts used to control compilation and installation of the +executable. However, as a special exception, the source code distributed need not +include anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the operating +system on which the executable runs, unless that component itself accompanies the +executable. +<P></P> +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. +<P></P> +<OL START="4"><LI> You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate your +rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so long +as such parties remain in full compliance. +<P></P> +<LI> You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program or +its derivative works. These actions are prohibited by law if you do not accept +this License. Therefore, by modifying or distributing the Program (or any work +based on the Program), you indicate your acceptance of this License to do so, +and all its terms and conditions for copying, distributing or modifying the +Program or works based on it. +<P></P> +<LI> Each time you redistribute the Program (or any work based on the Program), the +recipient automatically receives a license from the original licensor to copy, +distribute or modify the Program subject to these terms and conditions. You +may not impose any further restrictions on the recipients' exercise of the rights granted herein. +<P></P> +</OL>You are not responsible for enforcing compliance by third parties to this +License. +<P></P> +<OL START="7"><LI> If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this +License. If you cannot distribute so as to satisfy simultaneously your obligations +under this License and any other pertinent obligations, then as a consequence +you may not distribute the Program at all. For example, if a patent license +would not permit royalty-free redistribution of the Program by all those who +receive copies directly or indirectly through you, then the only way you could +satisfy both it and this License would be to refrain entirely from distribution of +the Program. +<P></P> +</OL>If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and the +section as a whole is intended to apply in other circumstances. +<P></P> +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many people +have made generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that system; it is up +to the author/donor to decide if he or she is willing to distribute software +through any other system and a licensee cannot impose that choice. +<P></P> +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. +<P></P> +<OL START="8"><LI> If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this License +incorporates the limitation as if written in the body of this License. +<P></P> +<LI> The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. +<P></P> +</OL>Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and `any later version', you have the option of following the terms and conditions either of that +version or of any later version published by the Free Software Foundation. If the +Program does not specify a version number of this License, you may choose any +version ever published by the Free Software Foundation. +<P></P> +<OL START="a"><LI> If you wish to incorporate parts of the Program into other free programs whose +distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, write to +the Free Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status of all +derivatives of our free software and of promoting the sharing and reuse of software +generally. +<P></P> +</OL>NO WARRANTY +<P></P> +<OL START="b"><LI> BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE +PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED +IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM `AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. +<P></P> +<LI> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY +COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +<P></P> +</OL>END OF TERMS AND CONDITIONS +<P></P> +<B>How to Apply These Terms to Your New Programs +<P></P> +</B>If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. +<P></P> +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the `copyright' line and a pointer to where the full notice is found. +<P></P> +<I>one line for the program's name and a brief idea of what it does. +<BR></I>Copyright (C) 19<I>yy</I> <I>name of author</I> +<BR> +<BR>This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. +<BR> +<BR>This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. +<BR> +<BR>You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA. +<P></P> +Also add information on how to contact you by electronic and paper mail. +<P></P> +If the program is interactive, make it output a short notice like the +following example when it starts in an interactive mode: +<P></P> +Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes +with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain +conditions; type `show c' for details. +<P></P> +The hypothetical commands <B>show w</B> and <B>show c</B> should show the appropriate parts of the General Public License. Of course, +the commands you use may be called something other than show w and show c; they can be mouse clicks or menu items—whatever suits your program. +<P></P> +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a `copyright disclaimer' for the program, if necessary. The following is a sample (when copying, alter +the names). +<P></P> +Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. +<BR> +<BR>signature of Ty Coon, 1 April 1989 +<BR>Ty Coon, President of Vice +<P></P> +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may consider +it more useful to permit linking proprietary applications with the library. If +this is what you want to do, use the GNU Library General Public License instead of this License. +<P></P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/gdb/gdbtk/library/help/trace/locals.html b/gdb/gdbtk/library/help/trace/locals.html new file mode 100644 index 00000000000..d0b1d2940e0 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/locals.html @@ -0,0 +1,83 @@ +<HTML> +<HEAD> +<TITLE>Locals Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Locals Window</H1> +<H2>Overview</H2> +<P>The Locals Window displays all local variables in scope. It may be used to +visualize local variables. Local variables need to be collected +before they can be viewed. See <A HREF="tracedlg.html#t_actions_add">Adding +an Action</A> in the Tracepoint Dialog for more information.</P> + +<P>Locals Window topics: +<UL> + <LI><UL><A HREF="#menus">Variable Menu</A> + <LI><A HREF="#menus_fmt">Format</A> + </UL> + <LI><UL><A HREF="#display">Locals Display</A> + <LI><A HREF="#display_deref">Dereferencing Pointers</A> + <LI><A HREF="#display_struct">Viewing a Structure or Class</A> + <LI><A HREF="#display_popup">Locals Pop-up Menu</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Variable Menu</A></H3> +The Variable Menu gives on-screen access to the funtions of the Locals Window. +To use any of these functions, first use the left mouse button to select a +variable from the display. Then select: + +<DL> + <DT><A NAME="menus_fmt">Format</A> + <DD>Change the display format of the variable +</DL> + +<H3><A NAME="display">Locals Display</A></H4> +The Locals Window Display consists of a scrolled listbox which contains all +local variables, one per line. Locals which were not collected at the current +tracepoint will display a memory-access error. To use any of the functions of +the Locals Window, use the left mouse button to select any element from the +Display. + +<P>Pointers, structures, and classes appear in the display with small exapansion +box before their names. To <A NAME="display_deref">dereference pointers</A> or +<A NAME="display_struct">view the members of classes or structures</A>, click +the closed expansion box (which appears as a small plus sign, "+") to "expand" +the listing. The expansion box changes to a minus sign, "-", indicating that the +display is now open. Pointers, structures and classes may be expanded recursively +to allow multiple pointer dereferences and embedded structure viewing. + +<P>The Locals Display updates as the trace buffer is navigated, highlighting +in blue those variables whose values have changed.</P> + +<P>The Locals Window will, by default, display all pointers in hexadecimal and all +other variables in decimal. To change the default display of variables, use the +"set output-radix" command in the console window. (Type "help set output-radix" in the +console window for help. To make this change permanent, it must be added to the user's +init file -- .gdbinit under unix and gdb.ini under Windows.) To change the display +format for a variable, select the Format option from either the Variable Menu or the +<A HREF="#display_popup">Locals Pop-up Menu</A>. +<BR> + +<H4><A NAME="display_popup">Locals Pop-up Menu</A></H4> +The Locals Pop-up Menu provides quick access to the functions of the Locals Window. +To use the Locals Pop-up Menu, first select a variable from the Display (by clicking +the left mouse button on it) and click the right mouse button, choosing from the +pop-up: +<DL> + <DT>Format + <DD>Change the display format of the variable. The variable may be displayed + as: + <DL> + <DT>Hex + <DD>hexadecimal (base 16) + <DT>Decimal + <DD>decimal (base 10) + <DT>Binary + <DD>binary (base 2) + <DT>Octal + <DD>octal (base 8) + </DL> +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/memory.html b/gdb/gdbtk/library/help/trace/memory.html new file mode 100644 index 00000000000..ad1cb36b9d1 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/memory.html @@ -0,0 +1,142 @@ +<HTML> +<HEAD> +<TITLE>Memory Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Memory Window</H1> +<H2>Overview</H2> +<P>The Memory Window allows users to display the contents of collected +memory. The Memory Window Preferences controls all of the display +characteristics of the Memory Window.</P> + +<P>Memory Window topics: +<UL> + <LI><UL><A HREF="#menus">Address Menu</A> + <LI><A HREF="#menus_auto">Auto Update</A> + <LI><A HREF="#menus_now">Update Now</A> + <LI><A HREF="#menus_prefs">Preferences</A> + </UL> + <LI><UL><A HREF="#display">Memory Display</A> + <LI><A HREF="#display_nav">Navigating the Memory Window</A> + <LI><A HREF="#display_popup">Memory Pop-up Menu</A> + </UL> + <LI><UL><A HREF="#prefs">Memory Window Preferences</A> + <LI><A HREF="#prefs_size">Size of the Display Cell</A> + <LI><A HREF="#prefs_fmt">Format of the Display Cell</A> + <LI><A HREF="#prefs_bytes">Size of the Memory Window</A> + <LI><A HREF="#prefs_misc">Miscellaneous</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Address Menu</A></H3> +<DL> + <DT><A NAME="menus_auto">Auto Update</A> + <DD>When selected, casues the Memory Window to update the Display. + <DT><A NAME="menus_now">Update Now</A> + <DD>Forces the Memory Window to update the Display. + <DT><A NAME="menus_prefs">Preferences</A> + <DD>Opens the Memory Window Preferences dialog. +</DL> + +<H3><A NAME="display">Memory Display</A></H3> +Like the <A HREF="register.html">Register Window</A>, the Memory Window +Display is organized into a spreadsheet. The address of any cell in the +Display can be determined by appeding the row and column headers for the +cell. Optionally, an ASCII display of the memory appears at the right. +Any non-ASCII-representable byte in memory will appear in the ASCII Display +as a control character (a dot, ".", by default). The <A HREF="#pref">Memory +Preferences Dialog</A> may be used to alter the appearance of the +Memory Window. Any uncollected memory will appear as "N/A", indicating that +this memory was not collected when the trace experiment was run. + +<P><A NAME="display_nav">To navigate the Memory Window</A>, use the mouse +and click the cell of interest. As an alternative, pressing the TAB key on +the keyboard will focus successive cells, from left to right, top to bottom. +The focus will wrap from the bottom of the Display to the top.</P> +<BR> + +<H4><A NAME="display_popup">Memory Pop-up Menu</A></H4> +Clicking the right mouse button while the mouse cursor lies within the +bounds of any cell will allow users to: +<DL> + <DT>Auto Update + <DD>When selected, the Memory Window will track changes in + memory shown in the Display. Cells in which changes have + occured will be highlighted. When not selected, the Memory + Window is "frozen", representing a "snapshot" of memory. + <DT>Update Now + <DD>Causes the Memory Window to update all the cells shown. + <DT>Go To <I>address</I> + <DD>The Memory Window Display is updated to show memory starting + at address <I>address</I>. + <DT>Open New Window at <I>address</I> + <DD>A new Memory Window is opened, displaying memory at address + <I>address</I> + <DT>Memory Preferences... + <DD>Opens the Memory Window Preferences for editing the appearance + of the Memory Window Display. +</DL> +<BR> + +<H3><A NAME="prefs">Memory Window Preferences</A></H3> +Memory Window Preference Dialog governs the appearance of the Memory Window: +the total number of bytes displayed, the size of each cell, ASCII control +character. +<BR> + +<H4><A NAME="prefs_size">Size of the Display Cells</A></H4> +This attribute controls how many bytes appear in each cell. Valid cell +sizes in the Memory Window may be: +<DL> + <DT>Byte + <DD>Each cell is exactly one byte + <DT>Half Word + <DD>Cells are displayed with two bytes + <DT>Word + <DD>Each cell contains four bytes + <DT>Double Word + <DD>Cells contain eight bytes + <DT>Float + <DD>Each cell contains four bytes, displayed as a floating point + number + <DT>Double Float + <DD>Cells are displayed as floating point, eight bytes each +</DL> +<BR> + +<H4><A NAME="prefs_fmt">Format of the Display Cells</A></H4> +The Format option of the Memory Preferences Dialog governs how the debugger +represents the memory. Possible representations include: + +<DL> + <DT>Binary + <DD>The values are shown as binary numbers + <DT>Signed Decimal + <DD>The values are shown as signed decimal numbers + <DT>Octal + <DD>Each cell is represented as an octal number + <DT>Unsigned Decimal + <DD>Values are displayed as unsigned decimals + <DT>Hex + <DD>Memory is displayed as a hexadecimal number. This is + the default. +</DL> +<BR> + +<H4><A NAME="prefs_bytes">Size of the Memory Window</A></H4> +The size of the memory window determines how much memory is actually +presented to the user. The total number of bytes shown can either be +determined by the size of the window, in which case resizing the Memory +Window will cause more or less memory to be displayed, or fixed at some +specified number of bytes. By default, the Memory Window shows 128 bytes +of memory. +<BR> + +<H4><A NAME="prefs_misc">Miscellaneous</A></H4> +Miscellaneous memory preferences include the option to display the ASCII +representation of the memory, including what character to use for non-ASCII +bytes (the "control" character). Additionally, users may specify the number +of bytes per row, either four, eight, sixteen, or thirty-two. The default is +sixteen bytes per row. +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/reg_pref.html b/gdb/gdbtk/library/help/trace/reg_pref.html new file mode 100644 index 00000000000..b21a5747df2 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/reg_pref.html @@ -0,0 +1,20 @@ +<HTML> +<HEAD> +<TITLE>Register Window Preferences Help</TITLE> +</HEAD> +<BODY> +<H1>Register Window Preferences</H1> +<H3>Overview</H3> +<P>Not yet done.</P> + +<P>Register Window Preferences topics: +<UL> + <LI><UL><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + </UL> +</UL></P> + +<H3><A NAME="">stuff</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/register.html b/gdb/gdbtk/library/help/trace/register.html new file mode 100644 index 00000000000..d0735593a12 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/register.html @@ -0,0 +1,105 @@ +<HTML> +<HEAD> +<TITLE>Register Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Register Window</H1> +<H2>Overview</H2> +<P>The Register Window lists all the registers and their contents for +the selected stack frame. It permits viewing the contents of registers +in different formats and some display customizations.</P> + +<P>Any register that was not collected will be displayed as having a value +of "0x0". To collect registers, add them to the collection action in the +<A HREF="tracedlg.html">Tracepoint Dialog</A>. + +<P>The Register Window will update the register contents in the display +to match the stack frame currently being viewed in the <A HREF="source.html"> +Source Window</A> and <A HREF="stack.html">Stack Winodw</A>.</P> + +<P>Register Window topics: +<UL> + <LI><UL><A HREF="#menus">Register Menu</A> + <LI><A HREF="#menus_fmt">Format</A> + <LI><A HREF="#menus_remove">Remove from Display</A> + <LI><A HREF="#menus_all">Display All Registers</A> + </UL> + <LI><UL><A HREF="#display">Register Display</A> + <LI><A HREF="#display_nav">Navigating the Register Display</A> + <LI><A HREF="#display_popup">Register Pop-up Menu</A> + <LI><A HREF="#display_format">Changing the Display Format of + a Register</A> + <LI><A HREF="#display_remove">Removing a Register + from the display</A> + <LI><A HREF="#display_all">Displaying all Registers</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Register Menu</A></H3> +The Register Menu provides on-screen access to the functionality of the +Register Window. To use any item from this menu, first use the mouse and +select (click the left mouse button) on any register cell. Users may then +select: +<BR> +<DL> + <DT><A NAME="menus_fmt"><A HREF="#display_format">Format</A></A> + <DD>Change the display format of the selected register + <DT><A NAME="menus_remove"><A HREF="#display_remove">Remove + from Display</A></A> + <DD>Remove the selected register from the Register + Window Display + <DT><A NAME="menus_all"><A HREF="#display_all">Display All + Registers</A></A> + <DD>Display all registers in the Display. This item + is only available when a register was previously + removed from the Display. +</DL> + +<H3><A NAME="display">Register Display</A></H3> +The Register Display contains name and value pairs for each register +available on the target hardware. These "cells" are layed out as a +spreadsheet for ease of use. + +<P><A NAME="display_nav"></A>To navigate the Register Display, use either +the mouse and left mouse button or the arrow keys on the keyboard to +highlight the appropriate cell. Users may then use the <A HREF="#menus"> +Register Menu</A> or use the Register Pop-up Menu to access special display +options for the Register Window.</P> +<BR> + +<H4><A NAME="display_popup">The Register Pop-up Menu</A></H4> +All of the special functions of the register window are accessed through +the Register Pop-up Menu. To use the Menu, simply select a register (see +<A HREF="#display_nav">Navigating the Register Display</A>) and click the +right mouse button. The Menu offers: +<DL> + <DT><A NAME="display_format">Format</A> + <DD><DL>Change the display format of the register. Valid display types + are: + <DT>Hex + <DD>The register's contents are displayed in + hexadecimal (base 16). + <DT>Decimal + <DD>The value is shown as + a decimal number (base 10). + <DT>Natural + <DD>The register is displayed in its natural format. + <DT>Binary + <DD>The contents of the register are displayed + as a binary number (base 2). + <DT>Octal + <DD>The register's contents are shown in octal (base 8). + <DT>Raw + <DD>The raw contents of the register are shown. + </DL> + <DT><A NAME="display_remove">Remove</A> + <DD>Remove the selected register from the display. To display + the removed register again, select the "Display All Registers" + option from the Register Menu or the Register Pop-up Menu. + <DT><A NAME="display_all">Display All Registers</A> + <DD>Causes the Register Window Display to show all registers, + including those which were previously "removed". This menu + item is only available when removed registers exist. +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/source.html b/gdb/gdbtk/library/help/trace/source.html new file mode 100644 index 00000000000..9ec0005227b --- /dev/null +++ b/gdb/gdbtk/library/help/trace/source.html @@ -0,0 +1,371 @@ +<HTML> +<HEAD> +<TITLE>Source Window Help</TITLE> +</HEAD> +<BODY> +<CENTER><H1>The Source Window</H1></CENTER> +<H3>Overview</H3> +<BR> +The Source Window is the primary interface between the user and the +debugger; it is automatically opened when the debugger starts. +The Source Window displays the status of the trace experiment, controls +navigation of the trace buffer, and allows visualization of the program +execution. + +<P>Source Window topics: +<UL> + <LI><UL><A HREF="#menus">Menus</A> + <LI><A HREF="#menus_file">File Menu</A> + <LI><A HREF="#menus_run">Run Menu</A> + <LI><A HREF="#menus_view">View Menu</A> + <LI><A HREF="#menus_trace">Trace Menu</A> + <LI><A HREF="#menus_prefs">Preferences Menu</A> + </UL> + <LI><UL><A HREF="#toolbar">Toolbar</A> + <LI><A HREF="#toolbar_exec">Trace Control Buttons</A> + <LI><A HREF="#toolbar_window">Window Buttons</A> + <LI><A HREF="#toolbar_frame">Frame Control</A> + </UL> + <LI><UL><A HREF="#display">Source Window Display</A> + <LI><A HREF="#display_balloon">Variable Balloons</A> + <LI><A HREF="#display_popup">Source Pop-up Mens</A> + </UL> + <LI><UL><A HREF="#status">Source Window Status Bars</A> + <LI><A HREF="#status_bar">Program Status Bar</A> + <LI><A HREF="#status_mode">Source Display Status Bar</A> + </UL> + <LI><A HREF="#search">Search Entry</A> +</UL></P> + +<H3><A NAME="menus">Menus</A></H3> +<H4><A NAME="menus_file">File Menu</A></H4> +The File menu contains the following items: +<DL> + <DT>Open + <DD>Opens a file selection dialog to select the executable to debug + <DT>Target Settings... + <DD>Opens the <A HREF="target.html">Target Selection Dialog</A> + to edit target settings + <DT>Page Setup + <DD>(Windows only) Opens the Windows Page Setup dialog to + configure printing + <DT>Print + <DD>(Windows only) Print the contents of the Source Window Display + <DT>Exit + <DD>Exits the debugger +</DL> + +<H4><A NAME="menus_run">Run Menu</A></H4> +The Run menu contains the following items: +<DL> + <DT>Connect to target + <DD>Establish a connection to a target. This option will open + the <A HREF="target.html">Target Selection Dialog</A> if no + previous connection has been established in the current + session. + <DT>Begin Collection + <DD>Start collecting trace data on the target + <DT>End Collection + <DD>Stop collecting trace data on the target + <DT>Disconnect + <DD>Disconnect the debugger from the target +</DL> + +<H4><A NAME="menus_view">View Menu</A></H4> +The View menu contains the following items: +<DL> + <DT>Stack + <DD>Open a <A HREF="stack.html">Stack Window</A> + <DT>Registers + <DD>Open a <A HREF="register.html">Register Window</A> + <DT>Memory + <DD>Open a <A HREF="memory.html">Memory Window</A> + <DT>Watch Expressions + <DD>Open a <A HREF="watch.html">Watch Window</A> + <DT>Local Variables + <DD>Open a <A HREF="locals.html">Locals Window</A> + <DT>Tracepoints + <DD>Open a <A HREF="tp.html">Tracepoint Window</A> + <DT>Tdump + <DD>Open a <A HREF="tdump.html">Tracepoint Dump Window</A> + <DT>Console + <DD>Open a <A HREF="console.html">Console Window</A> +</DL> + +<H4><A NAME="menus_trace">Trace Menu</A></H4> +The Trace Menu contains the following items: +<DL> + <DT>Next Hit + <DD>Update all displays with the next tracepoint in the + tracepoint buffer + <DT>Previous Hit + <DD>Go to the previous tracepoint in the buffer + <DT>First Hit + <DD>View the first tracepoint in the buffer + <DT>Next Line Hit + <DD>Go to the next tracepoint in the buffer in the same + frame as the current tracepoint + <DT>Next Hit Here + <DD>Jump to the next reference of the current tracepoint + in the buffer + <DT>Tfind Line... + <DD>Opens a dialog allowing the user to specify which source + line to inpect in the tracepoint buffer + <DT>Tfind PC... + <DD>Opens a dialog allowing the user to specify the PC of the + tracepoint to view + <DT>Tfind Tracepoint... + <DD>Opens a dialog allowing the user to specify which tracepoint + to view (by number). This option is most commonly used in + conjunction with the <A HREF="console.html">Console Window</A>. +</DL> + +<H4><A NAME="menus_prefs">Preferences Menu</A></H4> +The Preferences menu contains the following items: +<DL> + <DT>Global + <DD>Opens the <A HREF="gbl_pref.html">Global Preferences Dialog</A> + and allows editing of global settings + <DT>Source + <DD>Opens the <A HREF="src_pref.html">Source Preferences Dialog</A> + and allows editing of Source Window settings + <DT>Register + <DD>Opens the <A HREF="reg_pref.html">Register Preferences Dialog</A> + and allows editing of Register Window settings +</DL> + +<H3><A NAME="toolbar">Toolbar</A></H3> +The Source Window toolbar consists of three functional sections: trace +control buttons, debugger window buttons, and stack frame control buttons. +<BR> + +<H4><A NAME="toolbar_exec">Tracing Control Buttons</A></H4> +These convenience buttons provide on-screen access to the most important +debugger tracing control functions: +<DL> + <DT><A NAME="run_button"><IMG SRC="%run"> TStart</A> or + <A NAME="stop_button"><IMG SRC="%stop"></A> TStop + <DD>The TStart Button causes the target to start collecting trace data + <DD>The TStop Button causes the target to stop collecting trace data + <DT>Next Hit + <DD>Update all displays with the next tracepoint in the + tracepoint buffer + <DT>Previous Hit + <DD>Go to the previous tracepoint in the buffer + <DT>First Hit + <DD>View the first tracepoint in the buffer + <DT>Next Line Hit + <DD>Go to the next tracepoint in the buffer in the same + frame as the current tracepoint + <DT>Next Hit Here + <DD>Jump to the next reference of the current tracepoint + in the buffer +</DL> + +<H4><A NAME="toolbar_window">Window Buttons</A></H4> +The Debugger Window buttons give instant access to the Debugger's +auxillary windows: +<DL> + <DT><A NAME="register_button"><IMG SRC="%register"></A> Registers + <DD>Open a <A HREF="register.html">Register Window</A> + <DT><A NAME="memory_button"><IMG SRC="%memory"></A> Memory + <DD>Open a <A HREF="memory.html">Memory Window</A> + <DT><A NAME="stack_button"><IMG SRC="%stack"></A> Stack + <DD>Open a <A HREF="stack.html">Stack Window</A> + <DT><A NAME="watch_button"><IMG SRC="%watch"></A> Watch Expressions + <DD>Open a <A HREF="watch.html">Watch Window</A> + <DT><A NAME="locals_button"><IMG SRC="%locals"></A> Local Variables + <DD>Open a <A HREF="locals.html">Locals Window</A> + <DT><A NAME="tracepoints_button">Tracepoints</A> + <DD>Open a <A HREF="tp.html">Tracepoint Window</A> + <DT>Tracepoint Dump Window + <DD>Open a <A HREF="tdump.html">Tdump Window</A> + <DT><A NAME="console_button"><IMG SRC="%console"></A> Console + <DD>Open a <A HREF="console.html">Console Window</A> +</DL> + +<H4><A NAME="toolbar_frame">Frame Control</A></H4> +The Frame Control area of the toolbar displays information about the PC of +the current frame, and the frame control buttons may be used to navigate +through the call stack. Whenever any of these buttons are used, both the +Source Window Display and the <A HREF="stack.html">Stack Window</A> will +show the selected frame. In order to use the Stack Window in tracing mode, +the stack pointer must be collected. +<DL> + <!-- is this a problem for windows? no file join? --> + <DT><IMG SRC="images/frame_info.gif"> Frame Information Display + <DD>The left half of the frame information display shows the + value of the PC in the current frame. The right half shows + the line number of the PC in the source file, if available. + <DT><A NAME="up_button"><IMG SRC="%up"></A> Up + <DD>Select and view the stack frame that called this one + <DT><A NAME="down_button"><IMG SRC="%down"></A> Down + <DD>Select and view the stack frame called by this one + <DT><A NAME="bottom_button"><IMG SRC="%bottom"></A> Bottom + <DD>Select and view the bottom-most stack frame +</DL> + +<H3><A NAME="display">Source Display</A></H3> +The Source Display is used for many things: browsing source code, setting, +editing, and deleting tracepoints, and a few other special functions. +Executable lines (those for which executable code was generated by the +compiler) are denoted with a marker (a dash, "-") in the first column of +the display. + +<P>The debugger highlights the PC in the current frame in either green, +indicating that the PC is in the current tracepoint, or gold, indicating +that the PC is contained in a frame that is not the current tracepoint, i.e., +as part of a stack backtrace. A blue highlight is used by the debugger to +indicate a browsing position. All highlight colors +are user-selectable in the <A HREF="src_pref.html">Source Preferences</A>.</P> +<BR> + +<H4><A NAME="setting_a_tracepoint">Setting a Tracepoint</A></H4> +Moving the mouse pointer over the "hot spot" of an executable line will change +the mouse cursor to a large dot. Clicking the left mouse button will then allow +tracepoint to be inserted at this line. If no tracepoint exists, the +<A HREF="tracedlg.html">Add Tracepoint Dialog</A> will appear. If a tracepoint +is installed, the dash in the left margin will change into a magenta breakdot. +If a tracepoint exists, the <A HREF="tracedlg.html">Edit Tracepoint Dialog</A> +appears, allowing either modification of the tracepoint or deletion of the +tracepoint. If the tracepoint is deleted, the breakdot will revert to a dash.</P> + +<P>The executable line marker shows the status of each line: an empty marker +(the dash) indicates that no tracepoint is set at the line. A colored breakdot +indicates that a tracepoint exists at the line.</P> + +<P>The display will attempt to show the value of variables in +<A NAME="display_balloon">variable balloons</A>. To activate a +variable balloon, simply hold the mouse cursor over the name of +a variable in the Source Display for a second or two: the debugger displays the +name of the variable, its type, and its value in a pop-up balloon. If the +variable was not collected, the Variable Balloon will show a memory-access error.</P> +<BR> + +<H4><A NAME="display_popup">Source Pop-up Menus</A></H4> +The Source Display has two pop-up menus. One is activated by clicking the +right mouse button when the mouse cursor is over an executable line marker's +hot spot. This pop-up menu provides access to: +<DL> + <DT>Set Tracepoint + <DD>Opens the <A HREF="#tracedlg">Add/Edit Tracepoint Dialog</A>, + which allows new tracepoints to be set and modification and + deletion of existing tracepoints. +</DL> + +<P>The other pop-up menu is activated by clicking the right mouse button +anywhere else in the Source Display. It is only available when a variable +or number in the display lies below the mouse cursor or is selected +(by clicking the left mouse button and dragging the mouse to highlight +the variable/number). The pop-up menu allows users to: +<DL> + <DT><A NAME="add_to_watch">Add <I>expr</I> to Watch</A> + <DD>Adds the selected expression to the <A HREF="watch.html">Watch + Window</A>, opening it, if necessary. + <DT>Dump Memory at <I>expr</I> + <DD>Opens a new <A HREF="memory.html">Memory Window</A> at the + selected expression. If the expression is a variable, then + the Memory Window is opened with memory addresses starting + at the value of the variable. + <DT>Set Tracepoint Range + <DD>This option is only available when a range of lines is highlighted + in the Source Display. It allows tracepoints with the same + properties to be set at every executable line in the range. If + any tracepoints exist in the range already, the debugger will + ask if the properties of the existing tracepoint should be + replaced with the properties of the range. +</DL> +</P> + +<H4><A NAME="status">Source Window Status Bars</A></H4> +The Source Window has two status bars which inform the user of the +status of the program (the "status bar") and the status of the Source +Window. + +<P>The <A NAME="status_bar">Program Status Bar</A> (or simply "Status Bar") +displays the status of the program. Common messages seen here include: +<DL> + <DT>No program loaded. + <DD>No program has been loaded into target memory. + <DT>Inspecting trace at <I>line/address</I> + <DD>The debugger is inspecting the tracepoint at line + <I>line</I> or address <I>address</I>. Use the + <A HREF="#toolbar_exec">Tracing Control Buttons</A> + to navigate through the trace buffer. +</DL> +<P>The Status Bar also displays some help information. For instance, +the Status Bar will show the function of a button on the toolbar or +the Source Display Status Bar as well as any keyboard shortcut for this +button.</P> +<BR> + +<H4><A NAME="status_mode">Source Display Status Bar</A></H4> +current state of the Source Window: the name of the file displayed in +the Display, the name of the function in the Display which contains +the PC for the current frame (if any), and the display mode. + +<P>The <A NAME="file_selector">Source File Selector</A> is a dropdown +menu which contains the names of all the files that were compiled into +the program being debugged.</P> + +<P>Normally, the File Selector displays the name of the file currently being +viewed, but any file from the dropdown menu may be selected for browsing. +Simply select the file to view from the available choices (or type it directly +into the File Selector) and the Source Window will load that file into +the Display. To return to the current tracepoint, simply press the +<A HREF="#bottom_button">Bottom Frame Control Button</A>.</P> + +<P>The <A NAME="function_selector">Source Function Selector</A> displays the +name of the function containing the Source Window's PC, if one exists, but it +may be used to browse any function in the current file. Simply type the name +of the desired function into the Function Selector or select it from the +dropdown menu. The Source Window's PC is updated to point at this function. +To return to the current tracepoint, simply press the +<A HREF="#bottom_button">Bottom Frame Control Button</A>.</P> + +<P>The <A NAME="mode_selector">Source Display Mode Selector</A> displays +the viewing mode of the current file/function shown in the Source +Window Display.</P> + +<P>The Display Mode Selector may be used to change the view of the current +source file. The available display modes are +<DL> + <DT>SOURCE + <DD>The contents of the Display are shown as source code. + If source code is not available (either because no debugging + information is available or the source file is not found), + the Source Window will revert the Display Mode to "ASSEMBLY". + <DT>ASSEMBLY + <DD>A disassembly of the target's memory is shown in the Display. + Even assembly source files show a disassembly of target memory; + to see the assembly source code, use the SOURCE mode. Note that the + debugger can only display assmebly code on a function-by-function + basis. It cannot display all the instructions generated from a single + source file. + <DT>MIXED + <DD>The Display shows source code mixed with the assembler + instructions which were generated for those lines by the + compiler for the current funtion. Note that the addresses + of the assembly lines is not necessarily monotonically + increasing. If the source file associated with the function + cannot be found, the Source Window will revert to ASSEMBLY mode. + <DT>SRC+ASM + <DD>The Source Window Display is divided into two panes: an + assembly pane and a source pane. Tracepoints may be set/cleared + in either pane. +</DL> +<BR> + +<H3><A NAME="search">Search Entry</A></H3> +The Search Entry facilitates searching for text in the Source Window Display. Simply enter the +text to be found into the Search Entry and press the Enter key on the keyboard to search +forwards in the Source Window Display (hold down ths Shift key to search backwards). If +a match is found, it is highlighted in the Source Window and the Program Status Bar +displays information about where the match was found. + +<P>The Search Entry can also jump the Source Window to a specific line. Enter the line +number preceeded by an at-sign (@) into the Search Entry and press enter. If entered +line number is greater than the total number of lines in the Source Window Display, +the Display will jump to the end of the current file.</P> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/src_pref.html b/gdb/gdbtk/library/help/trace/src_pref.html new file mode 100644 index 00000000000..e8547964653 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/src_pref.html @@ -0,0 +1,20 @@ +<HTML> +<HEAD> +<TITLE>Source Window Preferences Help</TITLE> +</HEAD> +<BODY> +<H1>Source Window Preferences</H1> +<H3>Overview</H3> +<P>Not yet done.</P> + +<P>Source Preferences topics: +<UL> + <LI><UL><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + <LI><A HREF="#">stuff</A> + </UL> +</UL></P> + +<H3><A NAME="">stuff</A></H3> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/stack.html b/gdb/gdbtk/library/help/trace/stack.html new file mode 100644 index 00000000000..25bbf0b54f4 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/stack.html @@ -0,0 +1,51 @@ +<HTML> +<HEAD> +<TITLE>Stack Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Stack Window</H1> +<H3>Overview</H3> +<P>The Stack Window allows users to view the call stack and jump between +levels of the stack. To use the Stack Window in tracepoint mode, the +stack pointer must be collected. See +<A HREF="tracedlg.html#t_actions_add">Adding an Action</A> in the Tracepoint +Dialog for more information on collecting registers.</P> + +<P>Stack Window topics: +<UL> + <LI><UL><A HREF="#display">Stack Display</A> + <LI><A HREF="#display_nav">Navigating the Stack Window</A> + <LI><A HREF="#display_lvl">Changing the Stack Level</A> + </UL> +</UL></P> + +<H3><A NAME="display">Stack Display</A></H3> +The Stack Display consists of a listbox which displays levels of the call stack +one per line. Each line contains the level number (useful when using the <A +HREF="console.html">Console Window</A>) and a description of the function executing +in that level. Typically, the function name and either the address of the function +or the file and line number where the function is defined are displayed. The +Stack Window may also be used to jump between levels of the stack. +<BR> + +<H4><A NAME="display_nav">Navigating the Stack Window</A></H4> +Navigation of the Stack Window is accomplished by clicking on the desired level +with the left mouse button. The <A HREF="source.html#display">Source Window +Display</A> updates to show the selected frame. All other secondary windows, +<A HREF="register.html">Registers</A>, <A HREF="watch.html">Watch</A>, and +<A HREF="locals.html">Locals</A> update their displays for the selected frame. +<BR> + +<H4><A NAME="display_lvl">Changing Stack Levels</A></H4> +To switch frames, simply click the left mouse button on the desired frame and the +debugger will switch contexts, updating all windows. The selected frame is highlighted +(in gold, by default). + +<P>As an alternative, changing stack levels may be accomplished via the +<A HREF="source.html#toolbar_frame">Frame Control Buttons</A> on the Source Window's +Toolbar. These buttons may be used to change frames one level at a time (either +immediately up or immediately down) or to jump to the bottom-most stack frame. +See <A HREF="source.html#toolbar_frame">Source Frame Control Buttons</A> for more +information.</P> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/target.html b/gdb/gdbtk/library/help/trace/target.html new file mode 100644 index 00000000000..83c6420a138 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/target.html @@ -0,0 +1,68 @@ +<HTML> +<HEAD> +<TITLE>Target Selection Help</TITLE> +</HEAD> +<BODY> +<H1>The Target Selection Dialog</H1> +<H3>Overview</H3> +<P>The Target Selection Dialog allows users to specify the debug target, +the interface used to connect to the target, and some useful run +options.</P> + +<P>Target Selection topics: +<UL> + <LI><UL><A HREF="#select">Selecting a Target</A> + <LI><A HREF="#select_tar">Specifying a Target</A> + <LI><A HREF="#select_int">Choosing a Connection Interface</A> + </UL> + <LI><UL><A HREF="#options">Run Options</A> + <LI><A HREF="#options_run_until_main">Run until 'main'</A> + <LI><A HREF="#options_bp_at_exit">Set breakpoint at 'exit'</A> + <LI><A HREF="#options_download_dialog">Display Download Dialog</A> + <LI><A HREF="#options_compare_to_remote_executable">Compare to + remote executable</A> + </UL> +</UL></P> + +<H3><A NAME="select">Selecting a Target</A></H3> +Selecting a target involves choosing a target for debugging and setting connection +interface options for the target. + +<P>Common targets include: "exec" for native debuggers, "remote" for establishing +a connection to a target board via a serial line, "remotetcp" for TCP connections, +and "sim" for connections to the simulator. There may be more depending on the +configuration of the debugger being used.</P> + +<P>In general, "remote" targets are always serial connections which require the user +to specify the serial port and baud rate to be used for the connection and +"remotetcp" targets are always TCP connections which require specifying the hostname +and port number of the machine to which to connect. Depending upon configuration, +there may be numerous serial- and TCP-based connections. These always follow the +naming convention <I>target</I> and <I>target</I>tcp.</P> + +<P>To <A NAME="select_tar"> select a target</A>, choose one of the available targets +from the dropdown menu in the Connection Frame. Then <A NAME="#select_int">specify +the interface options</A> for this target: selecting the baudrate and serial port +from the dropdown menus (serial targets only) or entering the hostname and port number +(TCP targets only).</P> + +<H3><A NAME="options">Run Options</A></H3> +Three run options which may be selected include: +<DL> + <DT><A NAME="options_run_until_main">Run until 'main' + <DD>Sets a breakpoint at main(). This has no effect when using + GDB in tracing mode. + <DT><A NAME="options_bp_at_exit">Set breakpoint at 'exit' + <DD>Sets a breakpoint at exit(). This has no effect when using + GDB in tracing mode. + <DT><A NAME="options_download_dialog">Display Download Dialog + <DD>Displays a dialog showing the progress of the download to + the target section by section. This has no effect when using + GDB in tracing mode. + <DT><A NAME="options_compare_to_remote_executable"> + Compare to remote executable</A> + <DD>When attaching to a tracing target, compare the host's and target's + executable by computing the checksum of each loadable section. +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/tdump.html b/gdb/gdbtk/library/help/trace/tdump.html new file mode 100644 index 00000000000..1850cb00373 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/tdump.html @@ -0,0 +1,16 @@ +<HTML> +<HEAD> +<TITLE>Trace Dump Window Help</TITLE> +</HEAD> +<BODY> +<H1>The TDump Window</H1> +<H3>Overview</H3> +<P>The Tdump Window displays all of the information contained in the +trace buffer for the current tracepoint. To view the contents of the +trace buffer for a specific tracepoint, use the <A HREF="source.html#toolbar_exec"> +Tracing Control Buttons</A> on the <A HREF="source.html#toolbar">Source Window Toolbar +</A>, or jump to the tracepoint using one of the Tfind Dialogs accessible +through the Source Window's <A HREF="source.html#menus_trace">Trace Menu</A>. +</P> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/tp.html b/gdb/gdbtk/library/help/trace/tp.html new file mode 100644 index 00000000000..471e1d545e9 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/tp.html @@ -0,0 +1,111 @@ +<HTML> +<HEAD> +<TITLE>Tracepoint Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Tracepoint Window</H1> +<H3>Overview</H3> +<P>The Tracepoint Window lists all the various tracepoints that exist in +the program. It facilitates modifying tracepoints (make them +temporary or normal, disabled or enabled) and removing tracepoints.</P> + +<P>Tracepoint Window topics: +<UL> + <LI><UL><A HREF="#menus">Menus</A> + <LI><A HREF="#menus_bp">Tracepoint Menu</A> + <LI><A HREF="#menus_global">Global Menu</A> + </UL> + <LI><UL><A HREF="#display">Tracepoint Display</A> + <LI><A HREF="#display_state">Enabling/Disabling Tracepoints</A> + <LI><A HREF="#display_remove">Removing Tracepoints</A> + <LI><A HREF="#display_popup">Tracepoint Pop-up Menu</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Menus</A></H3> +The Tracepoint Window contains two menus, one which deals specifically with +the individual tracepoints selected in the window, and one whose commands +affect all tracepoints. +<BR> + +<H4><A NAME="menus_bp">Tracepoint Menu</A></H4> +The Tracepoint Menu operates on the selected tracepoint only. The +state of a tracepoint may be changed by selecting the desired state +from the menu: +<DL> + <DT>Actions + <DD><A HREF="tracedlg.html">Display the Tracepoint Dialog</A> for + this tracepoint. + <DT>Enabled + <DD>The tracepoint is active and will stop the debugger + when it is hit. + <DT>Disabled + <DD>The tracepoint is being ignored. A disabled tracepoint + will never get hit. + <DT>Remove + <DD>Deletes the tracepoint +</DL> +<BR> + +<H4><A NAME="menus_global">Global Menu</A></H4> +Items on the Global Menu affect all defined tracepoints. Users may: +<DL> + <DT>Enable All + <DD>Enable all tracepoints + <DT>Disable All + <DD>Disable all tracepoints + <DT>Remove All + <DD>Delete all tracepoints +</DL> +<BR> + +<H4><A NAME="display">Tracepoint Display</A></H4> +The Tracepoint Display is a table of tracepoints. The first column of the +table (unlabeled) shows a checkbutton, indicating whether the tracepoint +is enabled (checked) or disabled (unchecked). Disabled tracepoints are +ignored and will not cause any actions to be performed on the target. + +<P>To use the Tracepoint Menu or the Tracepoint Pop-up Menu, first use +the left mouse button to select a tracepoint from the list, then make the +menu selection.</P> + +<H3>Modifying Tracepoints</H3> +To <A NAME="display_state">enable</A> a tracepoint, simply click the +checkbutton in the first column of the desired tracepoint so that it is +selected (checked). To disable a tracepoint, "uncheck" the checkbutton. + +<P>To remove a <A NAME="display_remove">tracepoint</A>, use the left mouse +button to select the tracepoint to remove and use either the tracepoint Menu +or the Tracepoint Pop-up Menu to select "remove". To re-install a tracepoint, +use the <A HREF="source.html#setting_a_tracepoint">Source Window Display</A>. +</P> +<BR> + +<H4><A NAME="display_popup">Tracepoint Pop-up Menu</A></H4> +The Tracepoint Pop-up Menu is accessed by using the mouse cursor to select +a tracepoint from the Tracepoint Display and then clicking the right button +on the mouse. The Pop-up allows expert users quicker access to the functions +of the Tracepoint Menu: +<DL> + <DT>Actions + <DD>Display the <A HREF="tracedlg.html">Tracepoint Dialog</A> for + the selected tracepoint. This allows the tracepoint's actions + to viewed or edited. + <DT>Enabled + <DD>The tracepoint is active and will causes actions to be + performed on the target when it is hit + <DT>Disabled + <DD>The tracepoint is being ignored. A disabled tracepoint + will never perform any actions or be recorded in the trace + buffer. + <DT>Remove + <DD>Deletes the tracepoint + <DT>Global, Enable All + <DD>Enable all tracepoints + <DT>Global, Disable All + <DD>Disable all tracepoints + <DT>Global, Remove All + <DD>Delete all tracepoints +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/tracedlg.html b/gdb/gdbtk/library/help/trace/tracedlg.html new file mode 100644 index 00000000000..0ad9504471b --- /dev/null +++ b/gdb/gdbtk/library/help/trace/tracedlg.html @@ -0,0 +1,134 @@ +<HTML> +<HEAD> +<TITLE>Tracepoint Dialogs Help</TITLE> +</HEAD> +<BODY> +<H1>Tracepoint Dialogs</H1> +<H3>Overview</H3> +<P>There are two Tracepoint Dialogs which help users set tracepoints: +The Tracepoint Dialog is used to view and add actions and The Actions +Dialog is used to edit a particular action specified in the +tracepoint's Action List.</P> + +<P>Tracepoint Dialogs topics: +<UL> + <LI><A HREF="#tracedlg">The Tracepoint Dialog</A> + <UL> + <LI><A HREF="#t_experiment">Experiment Frame</A> + <LI><A HREF="#t_actions">Actions Frame</A> + <UL> + <LI><A HREF="#t_actions_passcount">Number of Passes</A> + <LI><A HREF="#t_actions_add">Adding Actions</A> + <LI><A HREF="#t_actions_modify">Modifying Actions</A> + </UL> + </UL> + <LI><A HREF="#actionsdlg">The Actions Dialog</A> + <UL> + <LI><A HREF="#a_variables">Variables List</A> + <LI><A HREF="#a_collect">Collection List</A> + <LI><A HREF="#a_other">Other Entry</A> + </UL> +</UL></P> + +<H3><A NAME="tracedlg">The Tracepoint Dialog</H3> +The Tracepoint Dialog is the gateway to viewing and editing +the properties of any tracepoint. The same dialog is used +to add new tracepoints and edit and delete existing tracepoints, +for both single tracepoints and ranges of tracepoints. + +<H4><A NAME="t_experiment">Experiment Frame</A></H4> +The Experiment Frame displays information about the tracepoint's +location in the program and its status. Specifically, +<DL> + <DT>Number + <DD>The internal number for this tracepoint. New tracepoints + all have the number "-1". This number may be used to + refer to specific tracepoints when using the + <A HREF="console.html">Console Window</A> + <DT>Hit Count + <DD>The number of times the tracepoint has been hit + <DT>Thread + <DD>The thread in which the tracepoint exists. This + feature is not currently implemented. + <DT>Function + <DD>The function in which the tracepoint is set + <DT>File + <DD>The file in which the tracepoint is set + <DT>Line(s) + <DD>The line at which the tracepoint is set or the + lines which the tracepoint range affects +</DL> +<BR> + +<H4><A NAME="t_actions">Actions Frame</A></H4> +The Actions Frame displays the user-settable properties of the +tracepoint, including all actions and a pass count. + +<P>A pass count specifies the number of times that the tracepoint +can be hit on the target before the tracing experiment ceases. A +pass count of five means that this tracepoint will issue a silent +"tstop" when it is hit the fifth time (after it has performed all +it actions). A pass count of zero (0) means that the tracepoint +will never causes the trace experiment to terminate on the target.</P> + +<P>To <A NAME="t_actions_add">add an action</A> for the tracepoint, +select the appropriate action from the Action ComboBox and click +"Add". The <A HREF="#actionsdlg">Action Dialog</A> appears to +allow editing the action's properties.</P> + +<P>Currently, there are two actions: collect and while-stepping. +Any number of collect actions may be added to specify that the +target should collect variables, registers, and memory when +it is hit. The while-stepping action may be used to collect +data for a specified number of machine instructions. Only one +while-stepping action may be specified for any tracepoint.</P> + +<P>To <A NAME="t_actions_modify">modify the actions</A> associated +with a tracepoint, double-click the left mouse button on the action +listed in the Action Frame, and the <A HREF="#actionsdlg">Actions +Dialog</A> will appear.</P> + +<P>To accept the tracepoint as displayed, click the OK button. To abort +installing or editing the tracepoint, click the CANCEL button. To delete +the tracepoint (if it is not a new tracepoint), click the DELETE button.</P> + +<H3><A NAME="actionsdlg">The Actions Dialog</A></H3> +The Actions Dialog is used to edit an action for the tracepoint. It +consists of two lists, one containing all (uncollected) local variables +(including function arguments) and registers, and one containing everything +being collected. + +<P>The <A NAME="#a_variables">Variables List</A> lists all uncollected local variables, +function arguments, and registers and may also display the special indentifiers +"All Locals", "All Arguments", and "All Registers". Global variables (and file static +variables) do not appear on the Variable List.</P> + +<P>To move a variable from the Variables List to the Collection List, double-click +the variable in the Variables List or select the variable in the Variable +List and press the "<<< Collect" button. To specify a range of variables to be +collected, select them in the Variables list and click the "<<< Collect" button.</P> + +<P><A NAME="a_collect">The Collection List displays all data being collected +by the action, including the special types "All Locals", "All Registers", and +"All Arguments", which specify that every local variable, every register, and +every function argument will be collected, respectively. Specifying a local +variable, for example, and "All Locals" will cause only the special identifier +"All Locals" to be sent to the target. Analogously, "All Registers" and "All +Arguments" also override any register or function argument specifically listed +in the Collection List.</P> + +<P>To remove data from the Collection List, double-click any of the entries listed +in the List, or select a range of data to be removed and press the "Ignore >>>" +button. All local variables, function arguments, registers, and special identifiers +will be returned to the Variable List, while any expression (memory ranges, globals) +will simply "disappear". To add these again, use the <A HREF="#a_other">Other Entry</A> +at the bottom of the display.</P> + +<P>The <A NAME="#a_other">Other Entry</A> can be used to move any variable listed in +either the Collection List or the Variable List to the other list. It can also +be used to specify expressions for collection, such as memory ranges and global variables. +Simply enter the name of the global variable or the expression and press the enter key on +the keyboard. If the expression is valid, it will be added/removed from the Collection +List.</P> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/trace/watch.html b/gdb/gdbtk/library/help/trace/watch.html new file mode 100644 index 00000000000..373ad183a96 --- /dev/null +++ b/gdb/gdbtk/library/help/trace/watch.html @@ -0,0 +1,118 @@ +<HTML> +<HEAD> +<TITLE>Watch Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Watch Window</H1> +<H3>Overview</H3> +<P>The Watch Window may be used to inspect any collected expression, including +global variables, static variables, local variables, function arguments, +and registers.</P> + +<P>Watch Window topics: +<UL> + <LI><UL><A HREF="#menus">Watch Menu</A> + <LI><A HREF="#menus_fmt">Format</A> + <LI><A HREF="#menus_remove">Remove</A> + </UL> + <LI><UL><A HREF="#new">Adding Watch Expressions</A> + <LI><A HREF="#new_ent">In the Watch Window</A> + <LI><A HREF="#new_src">In the Source Window</A> + <LI><A HREF="#new_cast">Casting Pointers</A> + </UL> + <LI><UL><A HREF="#display">Watch Display</A> + <LI><A HREF="#display_deref">Dereferencing Pointers</A> + <LI><A HREF="#display_struct">Viewing a Structure or Class</A> + <LI><A HREF="#display_popup">Watch Pop-up Menu</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Watch Menu</A></H3> +The Watch Menu gives on-screen access to the funtions of the Watch Window. +To use any of these functions, first use the left mouse button to select an +expression from the display. Then select: + +<DL> + <DT><A NAME="menus_fmt">Format</A> + <DD>Change the display format of the expression + <DT><A NAME="menus_remove">Remove</A> + <DD>Remove the expression from the Watch Window +</DL> + +<H3><A NAME="new">Adding Watch Expressions</A></H3> +<A NAME="new_ent">To add an expression to the Watch Window</A>, simply enter +the expression into the entry at the bottom of the window and press return +or click the "Add Watch" button. The expression is validated and added to the +Watch Window Display. + +<P><A NAME="new_src">To add an expression to the Watch Window from the +<A HREF="source.html">Source Window</A></A>, use the +"<A HREF="source.html#add_to_watch">Add to Watch</A>" option of the +<A HREF="source.html#display_popup">Source Window Pop-up Menu</A>.</P> + +<P>Any legal expression may be added to the Watch Window, which will +evaluate each of its expressions everytime the program runs. Be cautious +adding expressions which cause assignments, such as "<CODE>i++</CODE>".</P> + +<P>Adding a register to the Watch Window can be advantages when debugging +via a slow serial line. In this case, keeping the entire Register Window open +may be inefficient. Consider adding the register to the Watch Window. Simply +enter the name of the register preceded with a dollar sign ($) into the +Entry. For example, to watch the PC register, enter "<CODE>$pc</CODE>" into +the Watch Window Entry. The program counter is added to the Display.</P> + +<P><A NAME="new_cast">To cast pointers</A>, simply enter the cast into the +Watch Window Entry at the bottom of the window. Use the same syntax for the +cast that the source file uses. If the source file uses C, the a simple +cast of "<CODE>ptr</CODE>" of type "<CODE>void *</CODE>" can be cast to type +"<CODE>my_struct</CODE>" by entering "<CODE>(my_struct *) ptr</CODE>" into +the Entry.</P> + +<H3><A NAME="display">Watch Display</A></H3> +The Watch Window Display consists of a scrolled listbox which contains all +watch expressions, one per line. To use any of the functions of the Watch +Window, use the left mouse button to select any element from the Display. + +<P>Pointers, structures, and classes appear in the display with a small +exapansion box before their names. To <A NAME="display_deref">dereference +pointers</A> or <A NAME="display_struct">view the members of classes or +structures</A>, click the closed expansion box (which appears as a small +plus sign, "+") to "expand" the listing. The expansion box changes to a +minus sign, "-", indicating that the display is now open. Pointers, +structures and classes may be expanded recursively to allow multiple pointer +dereferences and embedded structure viewing. + +<P>The Locals Display updates as the trace buffer is navigated, highlighting +in blue those variables whose values have changed.</P> + +<P>The Watch Window will, by default, display all pointers in hexadecimal and all +other variables in decimal. To change the default display of variables, use the +"set output-radix" command in the console window. (Type "help set output-radix" in the +console window for help. To make this change permanent, it must be added to the user's +init file -- .gdbinit under unix and gdb.ini under Windows.) To change the display +format for a variable, select the Format option from either the Variable Menu or the +<A HREF="#display_popup">Watch Pop-up Menu</A>. +<BR> + +<H4><A NAME="display_popup">Watch Pop-up Menu</A></H4> +The Watch Pop-up Menu provides quick access to the functions of the Watch Window. +To use the Locals Pop-up Menu, first select an expression from the Display (by +clicking the left mouse button on it) and click the right mouse button, choosing +from the pop-up: +<DL> + <DT>Format + <DD>Change the display format of the expression. The expression may be + displayed as: + <DL> + <DT>Hex + <DD>hexadecimal (base 16) + <DT>Decimal + <DD>decimal (base 10) + <DT>Binary + <DD>binary (base 2) + <DT>Octal + <DD>octal (base 8) + </DL> +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/help/watch.html b/gdb/gdbtk/library/help/watch.html new file mode 100644 index 00000000000..51734404534 --- /dev/null +++ b/gdb/gdbtk/library/help/watch.html @@ -0,0 +1,129 @@ +<HTML> +<HEAD> +<TITLE>Watch Window Help</TITLE> +</HEAD> +<BODY> +<H1>The Watch Window</H1> +<H3>Overview</H3> +<P>The Watch Window may be used to inspect and edit any expression, including +global variables, static variables, local variables, function arguments, +and registers.</P> + +<P>Watch Window topics: +<UL> + <LI><UL><A HREF="#menus">Watch Menu</A> + <LI><A HREF="#menus_edit">Edit</A> + <LI><A HREF="#menus_fmt">Format</A> + <LI><A HREF="#menus_remove">Remove</A> + </UL> + <LI><UL><A HREF="#new">Adding Watch Expressions</A> + <LI><A HREF="#new_ent">In the Watch Window</A> + <LI><A HREF="#new_src">In the Source Window</A> + <LI><A HREF="#new_cast">Casting Pointers</A> + </UL> + <LI><UL><A HREF="#display">Watch Display</A> + <LI><A HREF="#display_deref">Dereferencing Pointers</A> + <LI><A HREF="#display_struct">Viewing a Structure or Class</A> + <LI><A HREF="#display_edit">Editing an Expression</A> + <LI><A HREF="#display_popup">Watch Pop-up Menu</A> + </UL> +</UL></P> + +<H3><A NAME="menus">Watch Menu</A></H3> +The Watch Menu gives on-screen access to the funtions of the Watch Window. +To use any of these functions, first use the left mouse button to select an +expression from the display. Then select: + +<DL> + <DT><A NAME="menus_edit">Edit</A> + <DD>Edit the value of the expression + <DT><A NAME="menus_fmt">Format</A> + <DD>Change the display format of the expression + <DT><A NAME="menus_remove">Remove</A> + <DD>Remove the expression from the Watch Window +</DL> + +<H3><A NAME="new">Adding Watch Expressions</A></H3> +<A NAME="new_ent">To add an expression to the Watch Window</A>, simply enter +the expression into the entry at the bottom of the window and press return +or click the "Add Watch" button. The expression is validated and added to the +Watch Window Display. + +<P><A NAME="new_src">To add an expression to the Watch Window from the +<A HREF="source.html">Source Window</A></A>, use the +"<A HREF="source.html#add_to_watch">Add to Watch</A>" option of the +<A HREF="source.html#display_popup">Source Window Pop-up Menu</A>.</P> + +<P>Any legal expression may be added to the Watch Window, which will +evaluate each of its expressions everytime the program runs. Be cautious +adding expressions which cause assignments, such as "<CODE>i++</CODE>".</P> + +<P>Adding a register to the Watch Window can be advantages when debugging +via a slow serial line. In this case, keeping the entire Register Window open +may be inefficient. Consider adding the register to the Watch Window. Simply +enter the name of the register preceded with a dollar sign ($) into the +Entry. For example, to watch the PC register, enter "<CODE>$pc</CODE>" into +the Watch Window Entry. The program counter is added to the Display.</P> + +<P><A NAME="new_cast">To cast pointers</A>, simply enter the cast into the +Watch Window Entry at the bottom of the window. Use the same syntax for the +cast that the source file uses. If the source file uses C, the a simple +cast of "<CODE>ptr</CODE>" of type "<CODE>void *</CODE>" can be cast to type +"<CODE>my_struct</CODE>" by entering "<CODE>(my_struct *) ptr</CODE>" into +the Entry.</P> + +<H3><A NAME="display">Watch Display</A></H3> +The Watch Window Display consists of a scrolled listbox which contains all +watch expressions, one per line. To use any of the functions of the Watch +Window, use the left mouse button to select any element from the Display. + +<P>Pointers, structures, and classes appear in the display with a small +exapansion box before their names. To <A NAME="display_deref">dereference +pointers</A> or <A NAME="display_struct">view the members of classes or +structures</A>, click the closed expansion box (which appears as a small +plus sign, "+") to "expand" the listing. The expansion box changes to a +minus sign, "-", indicating that the display is now open. Pointers, +structures and classes may be expanded recursively to allow multiple pointer +derefernces and embedded structure viewing. + +<P>The Watch Display updates after every execution of the program and +highlights in blue those expressions whose values have changed.</P> + +<P>The Watch Window will, by default, display all pointers and registers in +hexadecimal and all other expressions in decimal. To change the display +format for an expression, select the Format option from either the Watch Menu +or the <A HREF="#display_popup">Watch Pop-up Menu</A>. +<BR> + +<H4><A NAME="display_edit">Editing an Expression</A></H4> +To edit an expression, either double-click the left mouse button on the expression +in the Display or select the Edit option from either the Watch Menu or +the Watch Pop-up Menu. To abort editing an expression's value, simply press +the escape key on the keybaord. The expression's original value is restored. +<BR> + +<H4><A NAME="display_popup">Watch Pop-up Menu</A></H4> +The Watch Pop-up Menu provides quick access to the functions of the Watch Window. +To use the Locals Pop-up Menu, first select an expression from the Display (by +clicking the left mouse button on it) and click the right mouse button, choosing +from the pop-up: +<DL> + <DT>Edit + <DD>Edit the expression's value. See <A HREF="#display_edit"> + Editing an Expression</A> + <DT>Format + <DD>Change the display format of the expression. The expression may be + displayed as: + <DL> + <DT>Hex + <DD>hexadecimal (base 16) + <DT>Decimal + <DD>decimal (base 10) + <DT>Binary + <DD>binary (base 2) + <DT>Octal + <DD>octal (base 8) + </DL> +</DL> +</BODY> +</HTML> diff --git a/gdb/gdbtk/library/helpviewer.itb b/gdb/gdbtk/library/helpviewer.itb new file mode 100644 index 00000000000..a366b689979 --- /dev/null +++ b/gdb/gdbtk/library/helpviewer.itb @@ -0,0 +1,286 @@ +# Viewer for HTML help info +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ----------------------------------------------------------------------------- +# NAME: +# HtmlViewer::constructor +# +# SYNOPSIS: +# constructor args +# +# DESC: +# Creates the Help Viewer window. +# ----------------------------------------------------------------------------- +body HtmlViewer::constructor {args} { + window_name "Help" + eval itk_initialize $args + _buildwin +} + + +# ----------------------------------------------------------------------------- +# NAME: +# private method HtmlViewer::_buildwin +# +# SYNOPSIS: +# _buildwin args +# +# DESC: +# This function is called by the constructor to build the widget. It +# creates pulldown menus, buttons, a stack, and a scrolledhtml widget. +# Finally it loads help/index.html. This last step should change if +# this widget is ever used for anything but help. +# ----------------------------------------------------------------------------- +body HtmlViewer::_buildwin {} { + global GDBTK_LIBRARY gdb_ImageDir + + set _links [PageStack \#auto] + + # create pulldown menu + set menu [menu $itk_interior.m -tearoff 0] + $menu add cascade -menu $menu.file -label "File" -underline 0 + set _m [menu $menu.file] + $_m add command -label "Back" -underline 0 -command "$this back" + $_m add command -label "Forward" -underline 0 -command "$this forward" + $_m add command -label "Home" -underline 0 -command "$this link $file" + $_m add separator + $_m add command -label "Close" -underline 0 -command "delete object $this" + $menu add cascade -menu $menu.topic -label "Topics" -underline 0 + set _t [menu $menu.topic] + foreach t $topics { + $_t add command -label [lindex $t 0] -command "$this link [lindex $t 1]" + } + [winfo toplevel $itk_interior] configure -menu $menu + + # create buttons + set _f [frame $itk_interior.b] + button $_f.back -command "$this back" \ + -image [image create photo -file [file join $gdb_ImageDir back.gif]] + button $_f.fore -command "$this forward" \ + -image [image create photo -file [file join $gdb_ImageDir fore.gif]] + button $_f.home -command "$this link $file" \ + -image [image create photo -file [file join $gdb_ImageDir home.gif]] + standard_toolbar $_f $_f.back $_f.fore $_f.home + + _enable 0 back fore + + # create html widget + set _html [iwidgets::scrolledhtml $itk_interior.a -linkcommand "$this link"] + + # get things going by loading index.html + $_html import [file join $GDBTK_LIBRARY help $file] + $_links push $file + + pack $_f -side top -fill x + pack $_html -expand yes -fill both + +} + +# ----------------------------------------------------------------------------- +# NAME: public method PageStack::push +# SYNOPSIS: push val +# DESC: Pushes a value onto the stack. +# ----------------------------------------------------------------------------- +body PageStack::push {val} { + incr _ptr + incr _max + if {$_ptr < $_max} { + set _max $_ptr + } + set _stack($_ptr) $val +} + +# ----------------------------------------------------------------------------- +# NAME: public method PageStack::back +# SYNOPSIS: back +# DESC: Moves the stack pointer back by one. +# RETURNS: Returns the value on the stack, or 0 on error. +# ----------------------------------------------------------------------------- +body PageStack::back {} { + if {$_ptr > 0} { + incr _ptr -1 + return $_stack($_ptr) + } + return 0 +} + +# ----------------------------------------------------------------------------- +# NAME: public method PageStack::next +# SYNOPSIS: next +# DESC: Moves the stack pointer forward by one. +# RETURNS: Returns the value on the stack, or 0 on error. +# ----------------------------------------------------------------------------- +body PageStack::next {} { + if {$_ptr < $_max} { + incr _ptr + return $_stack($_ptr) + } + return 0 +} + +# ----------------------------------------------------------------------------- +# NAME: public method PageStack:more +# SYNOPSIS: more +# DESC: Indicates if the stack pointer is not at the top. +# RETURNS: Returns 1 if PageStack::next will suceed, 0 otherwise. +# ----------------------------------------------------------------------------- +body PageStack::more {} { + if {$_ptr < $_max} { + return 1 + } + return 0 +} + +# ----------------------------------------------------------------------------- +# NAME: public method PageStack:less +# SYNOPSIS: less +# DESC: Indicates if the stack pointer is not at the bottom of stack. +# RETURNS: Returns 1 if PageStack::back will suceed, 0 otherwise. +# ----------------------------------------------------------------------------- +body PageStack::less {} { + if {$_ptr > 0} { + return 1 + } + return 0 +} + +# ----------------------------------------------------------------------------- +# NAME: public method PageStack:current +# SYNOPSIS: current +# RETURNS: Returns the current value on the stack. +# ----------------------------------------------------------------------------- +body PageStack::current {} { + if {$_ptr > 0} { + return $_stack($_ptr) + } + return 0 +} + +# ------------------------------------------------------------------------------ +# NAME: +# private method HtmlViewer::_enable +# +# SYNOPSIS: +# _enable { on args } +# +# DESC: +# Enables or disables buttons and menus. +# +# ARGS: +# on - "1" to enable, "0" to disable +# args - things to enable/disable. May include "back", +# "fore", and "home" +# +# ------------------------------------------------------------------------------ +body HtmlViewer::_enable { on args } { + if {$on} { + set state normal + } else { + set state disabled + } + + foreach a $args { + switch $a { + back { + # set state of "back" + $_m entryconfigure 0 -state $state + $_f.back configure -state $state + } + fore { + # set state of "forward" + $_m entryconfigure 1 -state $state + $_f.fore configure -state $state + } + home { + # set state of "home" + $_m entryconfigure 2 -state $state + $_f.home configure -state $state + } + } + } +} + +# ------------------------------------------------------------------------------ +# NAME: public method HtmlViewer::back +# SYNOPSIS: back +# DESC: Moves to the previous page +# ------------------------------------------------------------------------------ +body HtmlViewer::back {} { + set res [$_links back] + if {$res != 0} { + load $res + if {![$_links less]} { + _enable 0 back + } + } +} + +# ------------------------------------------------------------------------------ +# NAME: public method HtmlViewer::forward +# SYNOPSIS: forward +# DESC: Moves to the next page +# ------------------------------------------------------------------------------ +body HtmlViewer::forward {} { + set res [$_links next] + if {$res != 0} { + load $res + if {![$_links more]} { + _enable 0 fore + } + } +} + +# ------------------------------------------------------------------------------ +# NAME: public method HtmlViewer::link +# SYNOPSIS: link page +# ARDS: page - link to the page to load +# DESC: Saves the page on the stack and calls the "load" method +# ------------------------------------------------------------------------------ +body HtmlViewer::link {page} { + if {$page != [$_links current]} { + $_links push $page + load $page + if {![$_links more]} { + _enable 0 fore + } + } +} + +# ------------------------------------------------------------------------------ +# NAME: private method HtmlViewer::load +# SYNOPSIS: load link +# DESC: Disables menus and buttons, sets cursor, loads a page into +# the html widget, then resets cursor and enables the menus +# and buttons +# ------------------------------------------------------------------------------ +body HtmlViewer::load {link} { + _enable 0 back fore home + $itk_interior configure -cursor watch + $_html import -link $link + $itk_interior configure -cursor "" + _enable 1 back fore home +} + +# ------------------------------------------------------------------------------ +# NAME: public proc HtmlViewer::open_help +# SYNOPSIS: HtmlViewer::open_help file +# DESC: If the prefs are set to use a browser, attempts +# to do so. Otherwise, uses builtin HtmlViewer class. +# ------------------------------------------------------------------------------ +body HtmlViewer::open_help {hfile} { + set link file://[file join $::GDBTK_LIBRARY help $hfile] + if {![pref get gdb/help/browser] || ![::open_url $link]} { + ManagedWin::open HtmlViewer -file $hfile + } +} diff --git a/gdb/gdbtk/library/helpviewer.ith b/gdb/gdbtk/library/helpviewer.ith new file mode 100644 index 00000000000..1959a718227 --- /dev/null +++ b/gdb/gdbtk/library/helpviewer.ith @@ -0,0 +1,97 @@ +# HtmlViewer class definition +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ----------------------------------------------------------------------------- +# NAME: +# class HtmlViewer +# +# DESC: +# This class implements a simple HTML browser. It has both pulldown +# menus and buttons for navigating. It uses the scrolledhtml iwidget +# to do its rendering. +# +# NOTES: +# Currently used as a help window. +# +# ----------------------------------------------------------------------------- +class HtmlViewer { + inherit EmbeddedWin + + public { + variable topics { + {index index.html} + {"Attach Dialog" attach.html} + {"Breakpoint Window" breakpoint.html} + {"Console Window" console.html } + {"Function Browser" browser.html } + {"Locals Window" locals.html } + {"Memory Window" memory.html} + {"Register Window" register.html} + {"Source Window" source.html} + {"Stack Window" stack.html} + {"Target Window" target.html } + {"Thread Window" thread.html } + {"Watch Window" watch.html} + } + variable file "index.html" + method back {} + method forward {} + method link {link} + method load {link} + method close {} + method constructor {args} + proc open_help {file} + } + + private { + variable _html + variable _links + variable _m + variable _f + + method _enable {on args} + method _buildwin {} + } + +} + +# ----------------------------------------------------------------------------- +# NAME: +# class PageStack +# +# DESC: +# Implements a stack-like class for saving and recalling items +# like pages in a help browser. It differs from a traditional +# stack only by the 'back' and 'next' methods which move up and +# down the stack without disturbing it, unlike 'push' and 'pop'. +# +# NOTES: +# Currently used by the HtmlViewer class. +# +# ----------------------------------------------------------------------------- +class PageStack { + private { + variable _ptr -1 + variable _max -1 + variable _stack + } + public { + method push {val} + method back {} + method next {} + method more {} + method less {} + method current {} + } +} diff --git a/gdb/gdbtk/library/images/Movie_off.gif b/gdb/gdbtk/library/images/Movie_off.gif Binary files differnew file mode 100644 index 00000000000..7fce569189e --- /dev/null +++ b/gdb/gdbtk/library/images/Movie_off.gif diff --git a/gdb/gdbtk/library/images/Movie_on.gif b/gdb/gdbtk/library/images/Movie_on.gif Binary files differnew file mode 100644 index 00000000000..51e29d679b2 --- /dev/null +++ b/gdb/gdbtk/library/images/Movie_on.gif diff --git a/gdb/gdbtk/library/images/back.gif b/gdb/gdbtk/library/images/back.gif Binary files differnew file mode 100644 index 00000000000..94602b4ac78 --- /dev/null +++ b/gdb/gdbtk/library/images/back.gif diff --git a/gdb/gdbtk/library/images/bottom.gif b/gdb/gdbtk/library/images/bottom.gif Binary files differnew file mode 100644 index 00000000000..82fe7ab0d2a --- /dev/null +++ b/gdb/gdbtk/library/images/bottom.gif diff --git a/gdb/gdbtk/library/images/bp.gif b/gdb/gdbtk/library/images/bp.gif Binary files differnew file mode 100644 index 00000000000..55a153d3e94 --- /dev/null +++ b/gdb/gdbtk/library/images/bp.gif diff --git a/gdb/gdbtk/library/images/build.gif b/gdb/gdbtk/library/images/build.gif Binary files differnew file mode 100644 index 00000000000..de301b272c1 --- /dev/null +++ b/gdb/gdbtk/library/images/build.gif diff --git a/gdb/gdbtk/library/images/check.gif b/gdb/gdbtk/library/images/check.gif Binary files differnew file mode 100644 index 00000000000..37ff7d3ce81 --- /dev/null +++ b/gdb/gdbtk/library/images/check.gif diff --git a/gdb/gdbtk/library/images/console.gif b/gdb/gdbtk/library/images/console.gif Binary files differnew file mode 100644 index 00000000000..e9412b20540 --- /dev/null +++ b/gdb/gdbtk/library/images/console.gif diff --git a/gdb/gdbtk/library/images/continue.gif b/gdb/gdbtk/library/images/continue.gif Binary files differnew file mode 100644 index 00000000000..c3babce52ee --- /dev/null +++ b/gdb/gdbtk/library/images/continue.gif diff --git a/gdb/gdbtk/library/images/cygnus.gif b/gdb/gdbtk/library/images/cygnus.gif Binary files differnew file mode 100644 index 00000000000..292fecc627f --- /dev/null +++ b/gdb/gdbtk/library/images/cygnus.gif diff --git a/gdb/gdbtk/library/images/down.gif b/gdb/gdbtk/library/images/down.gif Binary files differnew file mode 100644 index 00000000000..0a591f4ac29 --- /dev/null +++ b/gdb/gdbtk/library/images/down.gif diff --git a/gdb/gdbtk/library/images/edit.gif b/gdb/gdbtk/library/images/edit.gif Binary files differnew file mode 100644 index 00000000000..bc033dbc066 --- /dev/null +++ b/gdb/gdbtk/library/images/edit.gif diff --git a/gdb/gdbtk/library/images/file.gif b/gdb/gdbtk/library/images/file.gif Binary files differnew file mode 100644 index 00000000000..5e667f32133 --- /dev/null +++ b/gdb/gdbtk/library/images/file.gif diff --git a/gdb/gdbtk/library/images/finish.gif b/gdb/gdbtk/library/images/finish.gif Binary files differnew file mode 100644 index 00000000000..d717238c335 --- /dev/null +++ b/gdb/gdbtk/library/images/finish.gif diff --git a/gdb/gdbtk/library/images/fore.gif b/gdb/gdbtk/library/images/fore.gif Binary files differnew file mode 100644 index 00000000000..2eb9f76107d --- /dev/null +++ b/gdb/gdbtk/library/images/fore.gif diff --git a/gdb/gdbtk/library/images/gdbtk.gif b/gdb/gdbtk/library/images/gdbtk.gif Binary files differnew file mode 100644 index 00000000000..83c4cc155d9 --- /dev/null +++ b/gdb/gdbtk/library/images/gdbtk.gif diff --git a/gdb/gdbtk/library/images/gdbtk_icon.gif b/gdb/gdbtk/library/images/gdbtk_icon.gif Binary files differnew file mode 100644 index 00000000000..46f69e62852 --- /dev/null +++ b/gdb/gdbtk/library/images/gdbtk_icon.gif diff --git a/gdb/gdbtk/library/images/help.gif b/gdb/gdbtk/library/images/help.gif Binary files differnew file mode 100644 index 00000000000..061e2c600cc --- /dev/null +++ b/gdb/gdbtk/library/images/help.gif diff --git a/gdb/gdbtk/library/images/home.gif b/gdb/gdbtk/library/images/home.gif Binary files differnew file mode 100644 index 00000000000..ac71cd53388 --- /dev/null +++ b/gdb/gdbtk/library/images/home.gif diff --git a/gdb/gdbtk/library/images/icons.txt b/gdb/gdbtk/library/images/icons.txt new file mode 100644 index 00000000000..2a15b5b4994 --- /dev/null +++ b/gdb/gdbtk/library/images/icons.txt @@ -0,0 +1 @@ +Basic Icon Set diff --git a/gdb/gdbtk/library/images/insight.gif b/gdb/gdbtk/library/images/insight.gif Binary files differnew file mode 100644 index 00000000000..c3d93dcdef8 --- /dev/null +++ b/gdb/gdbtk/library/images/insight.gif diff --git a/gdb/gdbtk/library/images/less.gif b/gdb/gdbtk/library/images/less.gif Binary files differnew file mode 100644 index 00000000000..045025a8062 --- /dev/null +++ b/gdb/gdbtk/library/images/less.gif diff --git a/gdb/gdbtk/library/images/memory.gif b/gdb/gdbtk/library/images/memory.gif Binary files differnew file mode 100644 index 00000000000..1f62949d7d5 --- /dev/null +++ b/gdb/gdbtk/library/images/memory.gif diff --git a/gdb/gdbtk/library/images/more.gif b/gdb/gdbtk/library/images/more.gif Binary files differnew file mode 100644 index 00000000000..67cb020014e --- /dev/null +++ b/gdb/gdbtk/library/images/more.gif diff --git a/gdb/gdbtk/library/images/next.gif b/gdb/gdbtk/library/images/next.gif Binary files differnew file mode 100644 index 00000000000..99d1ea62ea7 --- /dev/null +++ b/gdb/gdbtk/library/images/next.gif diff --git a/gdb/gdbtk/library/images/next_check.gif b/gdb/gdbtk/library/images/next_check.gif Binary files differnew file mode 100644 index 00000000000..4488f04c76b --- /dev/null +++ b/gdb/gdbtk/library/images/next_check.gif diff --git a/gdb/gdbtk/library/images/next_frame.gif b/gdb/gdbtk/library/images/next_frame.gif Binary files differnew file mode 100644 index 00000000000..1bbc97932c5 --- /dev/null +++ b/gdb/gdbtk/library/images/next_frame.gif diff --git a/gdb/gdbtk/library/images/next_hit.gif b/gdb/gdbtk/library/images/next_hit.gif Binary files differnew file mode 100644 index 00000000000..d65295c099a --- /dev/null +++ b/gdb/gdbtk/library/images/next_hit.gif diff --git a/gdb/gdbtk/library/images/next_line.gif b/gdb/gdbtk/library/images/next_line.gif Binary files differnew file mode 100644 index 00000000000..96b374f65e3 --- /dev/null +++ b/gdb/gdbtk/library/images/next_line.gif diff --git a/gdb/gdbtk/library/images/nexti.gif b/gdb/gdbtk/library/images/nexti.gif Binary files differnew file mode 100644 index 00000000000..d2b65d4a551 --- /dev/null +++ b/gdb/gdbtk/library/images/nexti.gif diff --git a/gdb/gdbtk/library/images/open.gif b/gdb/gdbtk/library/images/open.gif Binary files differnew file mode 100644 index 00000000000..173290a2b9d --- /dev/null +++ b/gdb/gdbtk/library/images/open.gif diff --git a/gdb/gdbtk/library/images/opt.gif b/gdb/gdbtk/library/images/opt.gif Binary files differnew file mode 100644 index 00000000000..c5ad520f27e --- /dev/null +++ b/gdb/gdbtk/library/images/opt.gif diff --git a/gdb/gdbtk/library/images/prev_hit.gif b/gdb/gdbtk/library/images/prev_hit.gif Binary files differnew file mode 100644 index 00000000000..17ed5686ff9 --- /dev/null +++ b/gdb/gdbtk/library/images/prev_hit.gif diff --git a/gdb/gdbtk/library/images/reg.gif b/gdb/gdbtk/library/images/reg.gif Binary files differnew file mode 100644 index 00000000000..8efac2fd28f --- /dev/null +++ b/gdb/gdbtk/library/images/reg.gif diff --git a/gdb/gdbtk/library/images/rewind.gif b/gdb/gdbtk/library/images/rewind.gif Binary files differnew file mode 100644 index 00000000000..60b3d6135b1 --- /dev/null +++ b/gdb/gdbtk/library/images/rewind.gif diff --git a/gdb/gdbtk/library/images/run.gif b/gdb/gdbtk/library/images/run.gif Binary files differnew file mode 100644 index 00000000000..6f45f3a2a4d --- /dev/null +++ b/gdb/gdbtk/library/images/run.gif diff --git a/gdb/gdbtk/library/images/run_expt.gif b/gdb/gdbtk/library/images/run_expt.gif Binary files differnew file mode 100644 index 00000000000..1c5c37cbef3 --- /dev/null +++ b/gdb/gdbtk/library/images/run_expt.gif diff --git a/gdb/gdbtk/library/images/src.gif b/gdb/gdbtk/library/images/src.gif Binary files differnew file mode 100644 index 00000000000..a1890ef8759 --- /dev/null +++ b/gdb/gdbtk/library/images/src.gif diff --git a/gdb/gdbtk/library/images/stack.gif b/gdb/gdbtk/library/images/stack.gif Binary files differnew file mode 100644 index 00000000000..e17824a3592 --- /dev/null +++ b/gdb/gdbtk/library/images/stack.gif diff --git a/gdb/gdbtk/library/images/step.gif b/gdb/gdbtk/library/images/step.gif Binary files differnew file mode 100644 index 00000000000..776c8c3466a --- /dev/null +++ b/gdb/gdbtk/library/images/step.gif diff --git a/gdb/gdbtk/library/images/stepi.gif b/gdb/gdbtk/library/images/stepi.gif Binary files differnew file mode 100644 index 00000000000..d721c13e548 --- /dev/null +++ b/gdb/gdbtk/library/images/stepi.gif diff --git a/gdb/gdbtk/library/images/stop.gif b/gdb/gdbtk/library/images/stop.gif Binary files differnew file mode 100644 index 00000000000..d863aba7859 --- /dev/null +++ b/gdb/gdbtk/library/images/stop.gif diff --git a/gdb/gdbtk/library/images/tdump.gif b/gdb/gdbtk/library/images/tdump.gif Binary files differnew file mode 100644 index 00000000000..87db34c06c6 --- /dev/null +++ b/gdb/gdbtk/library/images/tdump.gif diff --git a/gdb/gdbtk/library/images/tools.gif b/gdb/gdbtk/library/images/tools.gif Binary files differnew file mode 100644 index 00000000000..cd0d1c7f805 --- /dev/null +++ b/gdb/gdbtk/library/images/tools.gif diff --git a/gdb/gdbtk/library/images/tools2_3d.gif b/gdb/gdbtk/library/images/tools2_3d.gif Binary files differnew file mode 100644 index 00000000000..5141fb62304 --- /dev/null +++ b/gdb/gdbtk/library/images/tools2_3d.gif diff --git a/gdb/gdbtk/library/images/tp.gif b/gdb/gdbtk/library/images/tp.gif Binary files differnew file mode 100644 index 00000000000..6ddf743a3fa --- /dev/null +++ b/gdb/gdbtk/library/images/tp.gif diff --git a/gdb/gdbtk/library/images/up.gif b/gdb/gdbtk/library/images/up.gif Binary files differnew file mode 100644 index 00000000000..df280098ebd --- /dev/null +++ b/gdb/gdbtk/library/images/up.gif diff --git a/gdb/gdbtk/library/images/vars.gif b/gdb/gdbtk/library/images/vars.gif Binary files differnew file mode 100644 index 00000000000..608fa9337b8 --- /dev/null +++ b/gdb/gdbtk/library/images/vars.gif diff --git a/gdb/gdbtk/library/images/vmake.gif b/gdb/gdbtk/library/images/vmake.gif Binary files differnew file mode 100644 index 00000000000..509d98a11a0 --- /dev/null +++ b/gdb/gdbtk/library/images/vmake.gif diff --git a/gdb/gdbtk/library/images/watch.gif b/gdb/gdbtk/library/images/watch.gif Binary files differnew file mode 100644 index 00000000000..077444d5fe1 --- /dev/null +++ b/gdb/gdbtk/library/images/watch.gif diff --git a/gdb/gdbtk/library/images/watch_movie.gif b/gdb/gdbtk/library/images/watch_movie.gif Binary files differnew file mode 100644 index 00000000000..855f703ac3f --- /dev/null +++ b/gdb/gdbtk/library/images/watch_movie.gif diff --git a/gdb/gdbtk/library/images2/Movie_off.gif b/gdb/gdbtk/library/images2/Movie_off.gif Binary files differnew file mode 100644 index 00000000000..7fce569189e --- /dev/null +++ b/gdb/gdbtk/library/images2/Movie_off.gif diff --git a/gdb/gdbtk/library/images2/Movie_on.gif b/gdb/gdbtk/library/images2/Movie_on.gif Binary files differnew file mode 100644 index 00000000000..51e29d679b2 --- /dev/null +++ b/gdb/gdbtk/library/images2/Movie_on.gif diff --git a/gdb/gdbtk/library/images2/back.gif b/gdb/gdbtk/library/images2/back.gif Binary files differnew file mode 100644 index 00000000000..67dd57e8ea9 --- /dev/null +++ b/gdb/gdbtk/library/images2/back.gif diff --git a/gdb/gdbtk/library/images2/bottom.gif b/gdb/gdbtk/library/images2/bottom.gif Binary files differnew file mode 100644 index 00000000000..1190cd2d2ad --- /dev/null +++ b/gdb/gdbtk/library/images2/bottom.gif diff --git a/gdb/gdbtk/library/images2/bp.gif b/gdb/gdbtk/library/images2/bp.gif Binary files differnew file mode 100644 index 00000000000..55a153d3e94 --- /dev/null +++ b/gdb/gdbtk/library/images2/bp.gif diff --git a/gdb/gdbtk/library/images2/build.gif b/gdb/gdbtk/library/images2/build.gif Binary files differnew file mode 100644 index 00000000000..6e4f7f2166b --- /dev/null +++ b/gdb/gdbtk/library/images2/build.gif diff --git a/gdb/gdbtk/library/images2/check.gif b/gdb/gdbtk/library/images2/check.gif Binary files differnew file mode 100644 index 00000000000..37ff7d3ce81 --- /dev/null +++ b/gdb/gdbtk/library/images2/check.gif diff --git a/gdb/gdbtk/library/images2/console.gif b/gdb/gdbtk/library/images2/console.gif Binary files differnew file mode 100644 index 00000000000..e9412b20540 --- /dev/null +++ b/gdb/gdbtk/library/images2/console.gif diff --git a/gdb/gdbtk/library/images2/continue.gif b/gdb/gdbtk/library/images2/continue.gif Binary files differnew file mode 100644 index 00000000000..99c0673cdec --- /dev/null +++ b/gdb/gdbtk/library/images2/continue.gif diff --git a/gdb/gdbtk/library/images2/cygnus.gif b/gdb/gdbtk/library/images2/cygnus.gif Binary files differnew file mode 100644 index 00000000000..292fecc627f --- /dev/null +++ b/gdb/gdbtk/library/images2/cygnus.gif diff --git a/gdb/gdbtk/library/images2/down.gif b/gdb/gdbtk/library/images2/down.gif Binary files differnew file mode 100644 index 00000000000..09ae742f225 --- /dev/null +++ b/gdb/gdbtk/library/images2/down.gif diff --git a/gdb/gdbtk/library/images2/edit.gif b/gdb/gdbtk/library/images2/edit.gif Binary files differnew file mode 100644 index 00000000000..6ff9082861e --- /dev/null +++ b/gdb/gdbtk/library/images2/edit.gif diff --git a/gdb/gdbtk/library/images2/file.gif b/gdb/gdbtk/library/images2/file.gif Binary files differnew file mode 100644 index 00000000000..247c722234b --- /dev/null +++ b/gdb/gdbtk/library/images2/file.gif diff --git a/gdb/gdbtk/library/images2/finish.gif b/gdb/gdbtk/library/images2/finish.gif Binary files differnew file mode 100644 index 00000000000..3e4a077185c --- /dev/null +++ b/gdb/gdbtk/library/images2/finish.gif diff --git a/gdb/gdbtk/library/images2/fore.gif b/gdb/gdbtk/library/images2/fore.gif Binary files differnew file mode 100644 index 00000000000..9a43be0eb86 --- /dev/null +++ b/gdb/gdbtk/library/images2/fore.gif diff --git a/gdb/gdbtk/library/images2/function.gif b/gdb/gdbtk/library/images2/function.gif Binary files differnew file mode 100644 index 00000000000..c61f38a2724 --- /dev/null +++ b/gdb/gdbtk/library/images2/function.gif diff --git a/gdb/gdbtk/library/images2/gdbtk.gif b/gdb/gdbtk/library/images2/gdbtk.gif Binary files differnew file mode 100644 index 00000000000..83c4cc155d9 --- /dev/null +++ b/gdb/gdbtk/library/images2/gdbtk.gif diff --git a/gdb/gdbtk/library/images2/gdbtk_icon.gif b/gdb/gdbtk/library/images2/gdbtk_icon.gif Binary files differnew file mode 100644 index 00000000000..46f69e62852 --- /dev/null +++ b/gdb/gdbtk/library/images2/gdbtk_icon.gif diff --git a/gdb/gdbtk/library/images2/help.gif b/gdb/gdbtk/library/images2/help.gif Binary files differnew file mode 100644 index 00000000000..1e127d6c0bb --- /dev/null +++ b/gdb/gdbtk/library/images2/help.gif diff --git a/gdb/gdbtk/library/images2/home.gif b/gdb/gdbtk/library/images2/home.gif Binary files differnew file mode 100644 index 00000000000..ac71cd53388 --- /dev/null +++ b/gdb/gdbtk/library/images2/home.gif diff --git a/gdb/gdbtk/library/images2/icons.txt b/gdb/gdbtk/library/images2/icons.txt new file mode 100644 index 00000000000..eefb6d2c6e3 --- /dev/null +++ b/gdb/gdbtk/library/images2/icons.txt @@ -0,0 +1 @@ +Windows-style Icon Set diff --git a/gdb/gdbtk/library/images2/insight.gif b/gdb/gdbtk/library/images2/insight.gif Binary files differnew file mode 100644 index 00000000000..c3d93dcdef8 --- /dev/null +++ b/gdb/gdbtk/library/images2/insight.gif diff --git a/gdb/gdbtk/library/images2/less.gif b/gdb/gdbtk/library/images2/less.gif Binary files differnew file mode 100644 index 00000000000..045025a8062 --- /dev/null +++ b/gdb/gdbtk/library/images2/less.gif diff --git a/gdb/gdbtk/library/images2/load.gif b/gdb/gdbtk/library/images2/load.gif Binary files differnew file mode 100644 index 00000000000..c97a9bfc00e --- /dev/null +++ b/gdb/gdbtk/library/images2/load.gif diff --git a/gdb/gdbtk/library/images2/memory.gif b/gdb/gdbtk/library/images2/memory.gif Binary files differnew file mode 100644 index 00000000000..1f62949d7d5 --- /dev/null +++ b/gdb/gdbtk/library/images2/memory.gif diff --git a/gdb/gdbtk/library/images2/more.gif b/gdb/gdbtk/library/images2/more.gif Binary files differnew file mode 100644 index 00000000000..67cb020014e --- /dev/null +++ b/gdb/gdbtk/library/images2/more.gif diff --git a/gdb/gdbtk/library/images2/next.gif b/gdb/gdbtk/library/images2/next.gif Binary files differnew file mode 100644 index 00000000000..9675812ce9c --- /dev/null +++ b/gdb/gdbtk/library/images2/next.gif diff --git a/gdb/gdbtk/library/images2/next_check.gif b/gdb/gdbtk/library/images2/next_check.gif Binary files differnew file mode 100644 index 00000000000..4488f04c76b --- /dev/null +++ b/gdb/gdbtk/library/images2/next_check.gif diff --git a/gdb/gdbtk/library/images2/next_frame.gif b/gdb/gdbtk/library/images2/next_frame.gif Binary files differnew file mode 100644 index 00000000000..1bbc97932c5 --- /dev/null +++ b/gdb/gdbtk/library/images2/next_frame.gif diff --git a/gdb/gdbtk/library/images2/next_hit.gif b/gdb/gdbtk/library/images2/next_hit.gif Binary files differnew file mode 100644 index 00000000000..d65295c099a --- /dev/null +++ b/gdb/gdbtk/library/images2/next_hit.gif diff --git a/gdb/gdbtk/library/images2/next_line.gif b/gdb/gdbtk/library/images2/next_line.gif Binary files differnew file mode 100644 index 00000000000..96b374f65e3 --- /dev/null +++ b/gdb/gdbtk/library/images2/next_line.gif diff --git a/gdb/gdbtk/library/images2/nexti.gif b/gdb/gdbtk/library/images2/nexti.gif Binary files differnew file mode 100644 index 00000000000..d05248fc6e1 --- /dev/null +++ b/gdb/gdbtk/library/images2/nexti.gif diff --git a/gdb/gdbtk/library/images2/open.gif b/gdb/gdbtk/library/images2/open.gif Binary files differnew file mode 100644 index 00000000000..173290a2b9d --- /dev/null +++ b/gdb/gdbtk/library/images2/open.gif diff --git a/gdb/gdbtk/library/images2/opt.gif b/gdb/gdbtk/library/images2/opt.gif Binary files differnew file mode 100644 index 00000000000..3f0d365e402 --- /dev/null +++ b/gdb/gdbtk/library/images2/opt.gif diff --git a/gdb/gdbtk/library/images2/prev_hit.gif b/gdb/gdbtk/library/images2/prev_hit.gif Binary files differnew file mode 100644 index 00000000000..17ed5686ff9 --- /dev/null +++ b/gdb/gdbtk/library/images2/prev_hit.gif diff --git a/gdb/gdbtk/library/images2/reg.gif b/gdb/gdbtk/library/images2/reg.gif Binary files differnew file mode 100644 index 00000000000..9f314a9bcf8 --- /dev/null +++ b/gdb/gdbtk/library/images2/reg.gif diff --git a/gdb/gdbtk/library/images2/rewind.gif b/gdb/gdbtk/library/images2/rewind.gif Binary files differnew file mode 100644 index 00000000000..60b3d6135b1 --- /dev/null +++ b/gdb/gdbtk/library/images2/rewind.gif diff --git a/gdb/gdbtk/library/images2/run.gif b/gdb/gdbtk/library/images2/run.gif Binary files differnew file mode 100644 index 00000000000..3a91e8efd37 --- /dev/null +++ b/gdb/gdbtk/library/images2/run.gif diff --git a/gdb/gdbtk/library/images2/run_expt.gif b/gdb/gdbtk/library/images2/run_expt.gif Binary files differnew file mode 100644 index 00000000000..1c5c37cbef3 --- /dev/null +++ b/gdb/gdbtk/library/images2/run_expt.gif diff --git a/gdb/gdbtk/library/images2/src.gif b/gdb/gdbtk/library/images2/src.gif Binary files differnew file mode 100644 index 00000000000..2b78909b2e9 --- /dev/null +++ b/gdb/gdbtk/library/images2/src.gif diff --git a/gdb/gdbtk/library/images2/stack.gif b/gdb/gdbtk/library/images2/stack.gif Binary files differnew file mode 100644 index 00000000000..e17824a3592 --- /dev/null +++ b/gdb/gdbtk/library/images2/stack.gif diff --git a/gdb/gdbtk/library/images2/step.gif b/gdb/gdbtk/library/images2/step.gif Binary files differnew file mode 100644 index 00000000000..00caaf8fccd --- /dev/null +++ b/gdb/gdbtk/library/images2/step.gif diff --git a/gdb/gdbtk/library/images2/stepi.gif b/gdb/gdbtk/library/images2/stepi.gif Binary files differnew file mode 100644 index 00000000000..a7217659018 --- /dev/null +++ b/gdb/gdbtk/library/images2/stepi.gif diff --git a/gdb/gdbtk/library/images2/stop.gif b/gdb/gdbtk/library/images2/stop.gif Binary files differnew file mode 100644 index 00000000000..92ce1afa7d8 --- /dev/null +++ b/gdb/gdbtk/library/images2/stop.gif diff --git a/gdb/gdbtk/library/images2/target.gif b/gdb/gdbtk/library/images2/target.gif Binary files differnew file mode 100644 index 00000000000..9aa9c3ac25c --- /dev/null +++ b/gdb/gdbtk/library/images2/target.gif diff --git a/gdb/gdbtk/library/images2/tdump.gif b/gdb/gdbtk/library/images2/tdump.gif Binary files differnew file mode 100644 index 00000000000..87db34c06c6 --- /dev/null +++ b/gdb/gdbtk/library/images2/tdump.gif diff --git a/gdb/gdbtk/library/images2/tools.gif b/gdb/gdbtk/library/images2/tools.gif Binary files differnew file mode 100644 index 00000000000..cd0d1c7f805 --- /dev/null +++ b/gdb/gdbtk/library/images2/tools.gif diff --git a/gdb/gdbtk/library/images2/tools2_3d.gif b/gdb/gdbtk/library/images2/tools2_3d.gif Binary files differnew file mode 100644 index 00000000000..5141fb62304 --- /dev/null +++ b/gdb/gdbtk/library/images2/tools2_3d.gif diff --git a/gdb/gdbtk/library/images2/tp.gif b/gdb/gdbtk/library/images2/tp.gif Binary files differnew file mode 100644 index 00000000000..6ddf743a3fa --- /dev/null +++ b/gdb/gdbtk/library/images2/tp.gif diff --git a/gdb/gdbtk/library/images2/up.gif b/gdb/gdbtk/library/images2/up.gif Binary files differnew file mode 100644 index 00000000000..262dbbf21c8 --- /dev/null +++ b/gdb/gdbtk/library/images2/up.gif diff --git a/gdb/gdbtk/library/images2/vars.gif b/gdb/gdbtk/library/images2/vars.gif Binary files differnew file mode 100644 index 00000000000..608fa9337b8 --- /dev/null +++ b/gdb/gdbtk/library/images2/vars.gif diff --git a/gdb/gdbtk/library/images2/vmake.gif b/gdb/gdbtk/library/images2/vmake.gif Binary files differnew file mode 100644 index 00000000000..509d98a11a0 --- /dev/null +++ b/gdb/gdbtk/library/images2/vmake.gif diff --git a/gdb/gdbtk/library/images2/watch.gif b/gdb/gdbtk/library/images2/watch.gif Binary files differnew file mode 100644 index 00000000000..077444d5fe1 --- /dev/null +++ b/gdb/gdbtk/library/images2/watch.gif diff --git a/gdb/gdbtk/library/images2/watch_movie.gif b/gdb/gdbtk/library/images2/watch_movie.gif Binary files differnew file mode 100644 index 00000000000..855f703ac3f --- /dev/null +++ b/gdb/gdbtk/library/images2/watch_movie.gif diff --git a/gdb/gdbtk/library/interface.tcl b/gdb/gdbtk/library/interface.tcl new file mode 100644 index 00000000000..3ff3d55b96f --- /dev/null +++ b/gdb/gdbtk/library/interface.tcl @@ -0,0 +1,1503 @@ +# Interface between GDB and Insight. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# This variable is reserved for this module. Ensure it is an array. +global gdbtk_state +set gdbtk_state(busyCount) 0 + +# This is run when a breakpoint changes. The arguments are the +# action, the breakpoint number, and the breakpoint info. +define_hook gdb_breakpoint_change_hook + +# This is run when a `set' command successfully completes in gdb. The +# first argument is the gdb variable name (as a Tcl list). The second +# argument is the new value. +define_hook gdb_set_hook + +#################################################################### +# # +# GUI STATE HOOKS # +# # +#################################################################### +# !!!!! NOTE !!!!! +# For debugging purposes, please put debug statements at the very +# beginning and ends of all GUI state hooks. + +# GDB_BUSY_HOOK +# This hook is used to register a callback when the UI should +# be disabled because the debugger is either busy or talking +# to the target. +# +# All callbacks should disable ALL user input which could cause +# any state changes in either the target or the debugger. +define_hook gdb_busy_hook + +# GDB_IDLE_HOOK +# This hook is used to register a callback when the UI should +# be enabled because the debugger is no longer busy. +# +# All callbacks should enable user input. These callbacks +# should also be as fast as possible to avoid any significant +# time delays when enabling the UI. +define_hook gdb_idle_hook + +# GDB_UPDATE_HOOK +# This hook is used to register a callback to update the widget +# when debugger state has changed. +define_hook gdb_update_hook + +# GDB_NO_INFERIOR_HOOK +# This hook is used to register a callback which should be invoked +# whenever there is no inferior (either at startup time or when +# an inferior is killed). +# +# All callbacks should reset their windows to a known, "startup" +# state. +define_hook gdb_no_inferior_hook + +# GDB_DISPLAY_CHANGE_HOOK +# This is run when a display changes. The arguments are the action, +# the breakpoint number, and (optionally) the value. +define_hook gdb_display_change_hook + +# GDB_TRACE_FIND_HOOK +# This hook is run by the trace find command. It is used to switch +# from control to browse mode when the user runs tfind commands... +# +define_hook gdb_trace_find_hook + +# ------------------------------------------------------------------ +# gdbtk_tcl_preloop - This function is called after gdb is initialized +# but before the mainloop is started. It sets the app name, and +# opens the first source window. +# ------------------------------------------------------------------ + +proc gdbtk_tcl_preloop { } { + global gdb_exe_name + + set_baud + + tk appname gdbtk + # If there was an error loading an executible specified on the command line + # then we will have called pre_add_symbol, which would set us to busy, + # but not the corresponding post_add_symbol. Do this here just in case... + after idle gdbtk_idle + set src [ManagedWin::open SrcWin] + debug "In preloop, with src: \"$src\" & error: \"$::errorInfo\"" + SrcWin::point_to_main + set msg "" + catch {gdb_cmd "info files"} msg + set line1 [string range $msg 0 [string first \n $msg]] + if {[regexp {Symbols from "(.*)"\.} $line1 dummy name]} { + set gdb_exe_name $name + } + gdbtk_update +} + + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_busy - run all busy hooks +# +# Use this procedure from within GUI code to indicate that +# the debugger is busy, either running the inferior or +# talking to the target. This will call all the registered +# gdb_busy_hook's. +# ------------------------------------------------------------------ +proc gdbtk_busy {} { + + set err [catch {run_hooks gdb_busy_hook} txt] + if {$err} { + debug "gdbtk_busy ERROR: $txt" + } + + # Force the screen to update + update +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_update - run all update hooks +# +# Use this procedure to force all widgets to update +# themselves. This hook is usually run after command +# that could change target state. +# ------------------------------------------------------------------ +proc gdbtk_update {} { + set err [catch {run_hooks gdb_update_hook} txt] + if {$err} { + debug "gdbtk_update ERROR: $txt" + } + + # Force the screen to update + update +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_idle - run all idle hooks +# +# Use this procedure to run all the gdb_idle_hook's, +# which should free the UI for more user input. This +# hook should only be run AFTER all communication with +# the target has halted, otherwise the risk of two (or +# more) widgets talking to the target arises. +# ------------------------------------------------------------------ +proc gdbtk_idle {} { + global gdb_running + + # Put the unfiltered hook back in place, just in case + # somebody swapped it out, and then died before they + # could replace it. + + gdb_restore_fputs + set err [catch {run_hooks gdb_idle_hook} txt] + if {$err} { + debug "gdbtk_idle 1 ERROR: $txt" + } + + if {!$gdb_running} { + set err [catch {run_hooks gdb_no_inferior_hook} txt] + if {$err} { + debug "gdbtk_idle 2 ERROR: $txt" + } + } + # Force the screen to update + update +} + +define_hook download_progress_hook + +# Random hook of procs to call just before exiting. +define_hook gdb_quit_hook + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_quit_check - Ask if the user really wants to quit. +# ------------------------------------------------------------------ +proc gdbtk_quit_check {} { + global gdb_downloading gdb_running + + if {$gdb_downloading} { + set msg "Downloading to target,\n really close the debugger?" + if {![gdbtk_tcl_query $msg no]} { + return 0 + } + } elseif {$gdb_running} { + # While we are running the inferior, gdb_cmd is fenceposted and returns + # immediately. Therefore, we need to ask here. Do we need to stop the target, + # too? + set msg "A debugging session is active.\n" + append msg "Do you still want to close the debugger?" + if {![gdbtk_tcl_query $msg no]} { + return 0 + } + } + return 1 +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_quit - Quit the debugger +# Call this procedure anywhere the user can request to quit. +# This procedure will ask all the right questions and run +# all the gdb_quit_hooks before exiting. +# ------------------------------------------------------------------ +proc gdbtk_quit {} { + if {[gdbtk_quit_check]} { + pref_save + gdb_force_quit + } +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_cleanup - called by GDB immediately +# before exiting. Last chance to cleanup! +# ------------------------------------------------------------------ +proc gdbtk_cleanup {} { + # This is a sign that it is too late to be doing updates, etc... + set ::gdb_shutting_down 1 +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_query - +# ------------------------------------------------------------------ +proc gdbtk_tcl_query {message {default yes}} { + global gdb_checking_for_exit gdbtk_state tcl_platform + + # FIXME We really want a Help button here. But Tk's brain-damaged + # modal dialogs won't really allow it. Should have async dialog + # here. + + set title "GDB" + set modal "task" + + # If we are checking whether to exit gdb, we want a system modal + # box. Otherwise it may be hidden by some other program, and the + # user will have no idea what is going on. + if {[info exists gdb_checking_for_exit] && $gdb_checking_for_exit} { + set modal "system" + } + + if {$tcl_platform(platform) == "windows"} { + # On Windows, we want to only ask each question once. + # If we're already asking the question, just wait for the answer + # to come back. + set ans [list answer $message] + set pending [list pending $message] + + if {[info exists gdbtk_state($pending)]} { + incr gdbtk_state($pending) + } else { + set gdbtk_state($pending) 1 + set gdbtk_state($ans) {} + + ide_messageBox [list set gdbtk_state($ans)] -icon warning \ + -default $default -message $message -title $title \ + -type yesno -modal $modal -parent . + } + + vwait gdbtk_state($ans) + set r $gdbtk_state($ans) + if {[incr gdbtk_state($pending) -1] == 0} { + # Last call waiting for this answer, so clear it. + unset gdbtk_state($pending) + unset gdbtk_state($ans) + } + } else { + # On Unix, apparently it doesn't matter how many times we ask a + # question. + set r [tk_messageBox -icon warning -default $default \ + -message $message -title $title \ + -type yesno -modal $modal -parent .] + } + + update idletasks + return [expr {$r == "yes"}] +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_warning - +# ------------------------------------------------------------------ +proc gdbtk_tcl_warning {message} { + debug "$message" + +# ADD a warning message here if the gui must NOT display it +# add the message at the beginning of the switch followed by - + + switch -regexp $message { + "Unable to find dynamic linker breakpoint function.*" {return} + default {show_warning $message} + } +} + +# ------------------------------------------------------------------ +# PROC: show_warning - +# ------------------------------------------------------------------ +proc show_warning {message} { + global tcl_platform + + # FIXME We really want a Help button here. But Tk's brain-damaged + # modal dialogs won't really allow it. Should have async dialog + # here. + set title "GDB" + set modal "task" + + if {$tcl_platform(platform) == "windows"} { + ide_messageBox -icon warning \ + -default ok -message $message -title $title \ + -type ok -modal $modal -parent . + } else { + set r [tk_messageBox -icon warning -default ok \ + -message $message -title $title \ + -type ok -modal $modal -parent .] + } +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_ignorable_warning - +# ------------------------------------------------------------------ +proc gdbtk_tcl_ignorable_warning {class message} { + catch {ManagedWin::open WarningDlg -center -transient \ + -message [list $message] -ignorable $class} +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_fputs - +# ------------------------------------------------------------------ +proc gdbtk_tcl_fputs {message} { + global gdbtk_state + # Restore the fputs hook, in case anyone forgot to put it back... + gdb_restore_fputs + + if {$gdbtk_state(console) != ""} { + $gdbtk_state(console) insert $message + } +} + +# ------------------------------------------------------------------ +# PROC: echo - +# ------------------------------------------------------------------ +proc echo {args} { + gdbtk_tcl_fputs [concat $args]\n +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_fputs_error - +# ------------------------------------------------------------------ +proc gdbtk_tcl_fputs_error {message} { + global gdbtk_state + # Restore the fputs hook, in case anyone forgot to put it back... + gdb_restore_fputs + + if {$gdbtk_state(console) != ""} { + $gdbtk_state(console) einsert $message + update + } +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_flush - +# ------------------------------------------------------------------ +proc gdbtk_tcl_flush {} { + debug [info level 0] +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_start_variable_annotation - +# ------------------------------------------------------------------ +proc gdbtk_tcl_start_variable_annotation {valaddr ref_type stor_cl + cum_expr field type_cast} { + debug [info level 0] +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_end_variable_annotation - +# ------------------------------------------------------------------ +proc gdbtk_tcl_end_variable_annotation {} { + debug [info level 0] +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_breakpoint - +# ------------------------------------------------------------------ +proc gdbtk_tcl_breakpoint {action bpnum addr line file bp_type enabled thread} { +# debug "BREAKPOINT: $action $bpnum $addr $line $file $bp_type $enabled $thread " + run_hooks gdb_breakpoint_change_hook $action $bpnum $addr $line $file $bp_type $enabled $thread +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_tracepoint - +# ------------------------------------------------------------------ +proc gdbtk_tcl_tracepoint {action tpnum addr line file pass_count} { +# debug "TRACEPOINT: $action $tpnum $addr $line $file $pass_count" + run_hooks gdb_breakpoint_change_hook $action $tpnum $addr $line $file tracepoint +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_trace_find_hook - +# ------------------------------------------------------------------ +proc gdbtk_tcl_trace_find_hook {arg from_tty} { +# debug "Running trace find hook with $arg $from_tty" + run_hooks gdb_trace_find_hook $arg $from_tty +} + +################################################################ +# +# Handle `readline' interface. +# + +# Run a command that is known to use the "readline" interface. We set +# up the appropriate buffer, and then run the actual command via +# gdb_cmd. Calls into the "readline" callbacks just return values +# from our list. + +# ------------------------------------------------------------------ +# PROC: gdb_run_readline_command - +# ------------------------------------------------------------------ +proc gdb_run_readline_command {command args} { + global gdbtk_state +# debug "run readline_command $command $args" + set gdbtk_state(readlineArgs) $args + gdb_cmd $command +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_readline_begin - +# ------------------------------------------------------------------ +proc gdbtk_tcl_readline_begin {message} { + global gdbtk_state +# debug "readline begin" + set gdbtk_state(readline) 0 + if {$gdbtk_state(console) != ""} { + $gdbtk_state(console) insert $message + } +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_readline - +# ------------------------------------------------------------------ +proc gdbtk_tcl_readline {prompt} { + global gdbtk_state +# debug "gdbtk_tcl_readline $prompt" + if {[info exists gdbtk_state(readlineArgs)]} { + # Not interactive, so pop the list, and print element. + set cmd [lvarpop gdbtk_state(readlineArgs)] + command::insert_command $cmd + } else { + # Interactive. +# debug "interactive" + set gdbtk_state(readline) 1 + $gdbtk_state(console) activate $prompt + vwait gdbtk_state(readline_response) + set cmd $gdbtk_state(readline_response) +# debug "got response: $cmd" + unset gdbtk_state(readline_response) + set gdbtk_state(readline) 0 + } + return $cmd +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_readline_end - +# ------------------------------------------------------------------ +proc gdbtk_tcl_readline_end {} { + global gdbtk_state +# debug "readline_end" + catch {unset gdbtk_state(readlineArgs)} + unset gdbtk_state(readlineActive) + command::end_multi_line_input +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_busy - this is called immediately before gdb +# executes a command. +# +# ------------------------------------------------------------------ +proc gdbtk_tcl_busy {} { + global gdbtk_state + if {[incr gdbtk_state(busyCount)] == 1} { + gdbtk_busy + } +} + +################################################################ +# +# +# + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_idle - this is called immediately after gdb +# executes a command. +# ------------------------------------------------------------------ +proc gdbtk_tcl_idle {} { + global gdbtk_state + if {$gdbtk_state(busyCount) > 0 + && [incr gdbtk_state(busyCount) -1] == 0} { + gdbtk_update + gdbtk_idle + } +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_tstart - +# ------------------------------------------------------------------ +proc gdbtk_tcl_tstart {} { + set srcwin [lindex [manage find src] 0] + $srcwin.toolbar do_tstop 0 + +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_tstop - +# ------------------------------------------------------------------ +proc gdbtk_tcl_tstop {} { + set srcwin [lindex [manage find src] 0] + $srcwin.toolbar do_tstop 0 + +} + + +# ------------------------------------------------------------------ +# PROC: gdbtk_tcl_display - +# +# A display changed. ACTION is `enable', `disable', `delete', +# `create', or `update'. VALUE is only meaningful in the `update' +# case. +# ------------------------------------------------------------------ +proc gdbtk_tcl_display {action number {value {}}} { + # Handle create explicitly. + if {$action == "create"} { + manage create_if_never data + } + run_hooks gdb_display_change_hook $action $number $value +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_register_changed +# This hook is called from value_assign to inform us that +# the user has changed the contents of a register. +# ------------------------------------------------------------------ +proc gdbtk_register_changed {} { + after idle gdbtk_update +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_memory_changed +# This hook is called from value_assign to inform us that +# the user has changed the contents of memory (including +# the program's variables). +# ------------------------------------------------------------------ +proc gdbtk_memory_changed {} { + after idle gdbtk_update +} + +#################################################################### +# # +# FILE HOOKS # +# # +# There are a number of hooks that are installed in gdb to # +# aid with file-like commands (selecting an exectuable and # +# loading symbols): # +# - exec_file_display_hook # +# Called in exec_file_command. The tcl hook is # +# "gdbtk_tcl_exec_file_display" # +# - file_changed_hook # +# Called in file_command. The tcl hook is # +# "gdbtk_tcl_file_changed" # +# - pre_add_symbol_hook # +# Called in symbol_file_add before loading. The tcl # +# hook is "gdbtk_tcl_pre_add_symbol" # +# - post_add_symbol_hook # +# Called in symbol_file_add when finished loading # +# a symbol file. The tcl hook is # +# "gdbtk_tcl_post_add_symbol" # +# # +# Together, these hooks should give the gui enough information # +# to cover the two most common uses of file commands: # +# 1. executable with symbols # +# 2. separate executable and symbol file(s) # +# # +#################################################################### +define_hook file_changed_hook + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_tcl_pre_add_symbol +# This hook is called before any symbol files +# are loaded so that we can inform the user. +# ------------------------------------------------------------------ +proc gdbtk_tcl_pre_add_symbol {file} { + + gdbtk_busy + + # Display some feedback to the user + set srcs [ManagedWin::find SrcWin] + foreach w $srcs { + $w set_status "Reading symbols from $file..." + } + update idletasks +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_tcl_post_add_symbol +# This hook is called after we finish reading a symbol +# file, so the source windows' combo boxes need filling. +# ------------------------------------------------------------------ +proc gdbtk_tcl_post_add_symbol {} { + + set srcs [ManagedWin::find SrcWin] + foreach w $srcs { + $w fillNameCB + } + gdbtk_idle +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_tcl_file_changed +# This hook is called whenever the exec file changes. +# This is called AFTER symbol reading, so it is +# ok to point to main when we get called. +# ------------------------------------------------------------------ +proc gdbtk_tcl_file_changed {filename} { + + SrcWin::point_to_main + run_hooks file_changed_hook +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_tcl_exec_file_display +# This hook is called from exec_file_command. It's purpose +# is to setup the gui for a new file. Note that we cannot +# look for main, since this hook is called BEFORE we +# read symbols. If the user used the "file" command, +# gdbtk_tcl_file_changed will set the source window to +# look at main. If the user used "exec-file" and "add-symbol" +# commands, then we cannot look for main. +# ------------------------------------------------------------------ +proc gdbtk_tcl_exec_file_display {filename} { + global gdb_loaded gdb_running gdb_exe_name gdb_target_changed + + # DO NOT CALL set_exe here! + + # Clear out the GUI, don't do it if filename is "" so that + # you avoid distracting flashes in the source window. + + if {$filename != ""} { + gdbtk_clear_file + } + + # set_exe calls file command with the filename in + # quotes, so we need to strip them here. + set gdb_exe_name [string trim $filename \'] + + SrcWin::point_to_main +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_locate_main +# This proc tries to locate a suitable main function from +# a list of names defined in the gdb/main_names preference; +# returns the linespec (see below) if found, or a null string +# if not. +# +# The return linespec looks like this: +# 0: basename of the file +# 1: function name +# 2: full filename +# 3: source line number +# 4: address +# 5: current PC - which will often be the same as address, but not when +# 6: shared library name if the pc is in a shared lib +# we are browsing, or walking the stack. +# +# ------------------------------------------------------------------ +proc gdbtk_locate_main {} { + set main_names [pref get gdb/main_names] + debug "gdbtk_locate_main: Searching $main_names" + foreach main $main_names { + if {![catch {gdb_search functions $main -static 1}] \ + && ![catch {gdb_loc $main} linespec]} { + return $linespec + } + } + return {} +} + +############################################## +# The rest of this file is an assortment of Tcl wrappers +# for various bits of gdb functionality. +# +############################################# + +# ------------------------------------------------------------------ +# PROC: set_exe_name - Update the executable name +# ------------------------------------------------------------------ +proc set_exe_name {exe} { + global gdb_exe_name gdb_exe_changed + #debug "set_exe_name: exe=$exe gdb_exe_name=$gdb_exe_name" + set gdb_exe_name $exe + set gdb_exe_changed 1 +} + + +# ------------------------------------------------------------------ +# PROC: set_exe - +# ------------------------------------------------------------------ +proc set_exe {} { + global gdb_exe_name gdb_exe_changed gdb_target_changed gdb_loaded file_done +# debug "gdb_exe_changed=$gdb_exe_changed gdb_exe_name=$gdb_exe_name" + if {$gdb_exe_changed} { + set gdb_exe_changed 0 + if {$gdb_exe_name == ""} { return } + set err [catch {gdb_cmd "file '$gdb_exe_name'" 1} msg] + if {$err} { + debug "set_exe ERROR: $msg" + set l [split $msg :] + set errtxt [join [lrange $l 1 end] :] + set msg "Error loading \"$gdb_exe_name\":\n" + append msg $errtxt + tk_messageBox -title "Error" -message $msg -icon error \ + -type ok + set gdb_exe_name {} + set file_done 0 + return + } elseif {[string match {*no debugging symbols found*} $msg]} { + tk_messageBox -icon error -default ok \ + -title "GDB" -type ok -modal system \ + -message "This executable has no debugging information." + set gdb_exe_name {} + set file_done 0 + return + } + + # force new target command + set gdb_target_changed 1 + set gdb_loaded 0 + set file_done 1 + } +} + +# ------------------------------------------------------------------ +# _open_file - open a file dialog to select a file for debugging. +# If filename is not "", then open this file. +# ------------------------------------------------------------------ + +proc _open_file {{file ""}} { + global gdb_running gdb_downloading tcl_platform + + if {$gdb_running || $gdb_downloading} { + # We are already running/downloading something.. + if {$gdb_running} { + set msg "A debugging session is active.\nAbort session and load new file?" + } else { + set msg "A download is in progress.\nAbort download and load new file?" + } + if {![gdbtk_tcl_query $msg no]} { + return 0 + } + } + + if {[string compare $file ""] == 0} { + set curFocus [focus] + + # Make sure that this is really a modal dialog... + # FIXME: Add a disable_all to ide_grab_support. + + ide_grab_support disable_except {} + + set file [tk_getOpenFile -parent . -title "Load New Executable"] + + ide_grab_support enable_all + + # If no one had the focus before, leave it that way (since I + # am not sure how this could happen... + + if {$curFocus != ""} { + raise [winfo toplevel $curFocus] + focus $curFocus + } + } elseif {![file exists $file]} { + tk_messageBox -message "File \"$file\" does not exist" + return 0 + } + + + if {$file == ""} { + return 0 + } + # Add the base dir for this file to the source search path. + set root [file dirname $file] + if {$tcl_platform(platform) == "windows"} { + set root [ide_cygwin_path to_posix $root] + set file [ide_cygwin_path to_posix $file] + } + + catch {gdb_cmd "cd $root"} + + # Clear out gdb's internal state, so that it will allow us + # (the gui) to ask the user questions. + gdb_clear_file + + # The gui needs to set this... + set_exe_name $file + + # set_exe needs to be called anywhere the gui does a file_command... + if {[set_exe] == "cancel"} { + gdbtk_update + gdbtk_idle + return 0 + } + + return 1 +} + +# ------------------------------------------------------------------ +# PROC: set_target_name - Update the target name. +# +# This function will prompt for a new target and update +# all variables. +# +# If $prompt is 0 it will just update gdb_target_cmd from gdb_target. +# +# RETURN: +# 1 if successful, +# 0 if the not (the user canceled the target selection dialog) +# ------------------------------------------------------------------ +proc set_target_name {{prompt 1}} { + global gdb_target_name gdb_target_changed gdb_exe_changed + global gdb_target_cmd gdb_pretty_name +# debug + set cmd_tmp $gdb_target_cmd + set name_tmp $gdb_target_name + +# debug "gdb_target_name=$gdb_target_name; name_tmp=$name_tmp" + if {$prompt} { + set win [ManagedWin::open TargetSelection -exportcancel 1 -center \ + -transient] + # need to call update here so the target selection dialog can take over + update idletasks + } + +# debug "gdb_target_name=$gdb_target_name" + if {$gdb_target_name == "CANCEL"} { + set gdb_target_cmd $cmd_tmp + set gdb_target_name $name_tmp + return 0 + } + set target $gdb_target_name + set targ [TargetSelection::getname $target cmd] + set gdb_target_cmd $cmd_tmp + set gdb_pretty_name [TargetSelection::getname $target pretty-name] + +# debug "target=$target pretty_name=$gdb_pretty_name" + set targ_opts "" + switch -regexp -- $gdb_target_name { + sim|ice { + set targ $gdb_target_name + set targ_opts [pref getd gdb/load/${gdb_target_name}-opts] + } + default { + set port [pref getd gdb/load/$target-port] + if {$port == ""} { + set port [pref get gdb/load/default-port] + } + set portnum [pref getd gdb/load/$target-portname] + if {$portnum == ""} { + set portnum [pref get gdb/load/default-portname] + } + set hostname [pref getd gdb/load/$target-hostname] + if {$hostname == ""} { + set hostname [pref get gdb/load/default-hostname] + } + # replace "com1" with the real port name + set targ [lrep $targ "com1" $port] + # replace "tcpX" with hostname:portnum + set targ [lrep $targ "tcpX" ${hostname}:${portnum}] + # replace "ethX" with hostname + set targ [lrep $targ "ethX" e=${hostname}] + } + } + +# debug "targ=$targ gdb_target_cmd=$gdb_target_cmd" + if {$gdb_target_cmd != $targ || $gdb_target_changed} { + set gdb_target_changed 1 + set gdb_target_cmd "$targ $targ_opts" + } + return 1 +} + +# ------------------------------------------------------------------ +# PROC: set_target - Change the target +# ------------------------------------------------------------------ +proc set_target {} { + global gdb_target_cmd gdb_target_changed gdb_pretty_name gdb_target_name +# debug "gdb_target_changed=$gdb_target_changed gdb_target_cmd=\"$gdb_target_cmd\"" +# debug "gdb_target_name=$gdb_target_name" + if {$gdb_target_cmd == "" && ![TargetSelection::native_debugging]} { + if {$gdb_target_name == ""} { + set prompt 1 + + # get the default + #set gdb_target_name [pref getd gdb/load/target] + } else { + set prompt 0 + } + if {![set_target_name $prompt]} { + set gdb_target_name "" + return CANCELED + } + } + + if {$gdb_target_changed} { + set srcWin [lindex [ManagedWin::find SrcWin] 0] + + $srcWin set_status "Trying to communicate with target $gdb_pretty_name" 1 + update + catch {gdb_cmd "detach"} + debug "CONNECTING TO TARGET: $gdb_target_cmd" + set err [catch {gdb_immediate "target $gdb_target_cmd"} msg ] + $srcWin set_status + + if {$err} { + if {[string first "Program not killed" $msg] != -1} { + return CANCELED + } + update + set dialog_title "GDB" + set debugger_name "GDB" + tk_messageBox -icon error -title $dialog_title -type ok \ + -modal task -message "$msg\n\n$debugger_name cannot connect to the target board\ +using [lindex $gdb_target_cmd 1].\nVerify that the board is securely connected and, if\ +necessary,\nmodify the port setting with the debugger preferences." + return ERROR + } + + if {![catch {pref get gdb/load/$gdb_target_name-after_attaching} aa] && $aa != ""} { + if {[catch {gdb_cmd $aa} err]} { + catch {[ManagedWin::find Console] einsert $err} + } + } + set gdb_target_changed 0 + return TARGET_CHANGED + } + return TARGET_UNCHANGED +} + +# ------------------------------------------------------------------ +# PROC: run_executable - +# +# This procedure is used to run an executable. It is called when the +# run button is used. +# ------------------------------------------------------------------ +proc run_executable { {auto_start 1} } { + global gdb_loaded gdb_downloading gdb_target_name + global gdb_exe_changed gdb_target_changed gdb_program_has_run + global gdb_running gdb_exe_name + +# debug "auto_start=$auto_start gdb_target_name=$gdb_target_name" + + set gdb_running_saved $gdb_running + set gdb_running 0 + + # No executable was specified. Prompt the user for one. + if {$gdb_exe_name == ""} { + if {[_open_file]} { + run_executable $auto_start + return + } else { + # The user canceled the load of a new executable. + return + } + } + + if {$gdb_downloading} { return } + if {[pref get gdb/control_target]} { + # Breakpoint mode + set_exe + + # Attach + if {$gdb_target_name == "" || [pref get gdb/src/run_attach]} { + if {[gdbtk_attach_target] == "ATTACH_CANCELED"} { + return + } + } + + # Download + if {[pref get gdb/src/run_load] && $gdb_target_name != "exec"} { + debug "Downloading..." + set gdb_loaded 0 + + # if the app has not been downloaded or the app has already + # started, we need to redownload before running + if {!$gdb_loaded} { + if {[Download::download_it]} { + # user cancelled the command +# debug "user cancelled the command $gdb_running" + set gdb_loaded 0 + gdbtk_update + gdbtk_idle + } + if {!$gdb_loaded} { + # The user cancelled the download after it started +# debug "User cancelled the download after it started $gdb_running" + gdbtk_update + gdbtk_idle + return + } + } + } + + # _Now_ set/clear breakpoints + if {[pref get gdb/load/exit] && ![TargetSelection::native_debugging]} { + debug "Setting new BP at exit" + catch {gdb_cmd "clear exit"} + catch {gdb_cmd "break exit"} + } + + if {[pref get gdb/load/main]} { + set main "main" + if {[set linespec [gdbtk_locate_main]] != ""} { + set main [lindex $linespec 1] + } + debug "Setting new BP at $main" + catch {gdb_cmd "clear $main"} + catch {gdb_cmd "break $main"} + } + + # set BP at user-specified function + if {[pref get gdb/load/bp_at_func]} { + foreach bp [pref get gdb/load/bp_func] { + debug "Setting BP at $bp" + catch {gdb_cmd "clear $bp"} + catch {gdb_cmd "break $bp"} + } + } + + # This is a hack. If the target is "sim" the opts are appended + # to the target command. Otherwise they are assumed to be command line + # args. What about simulators that accept command line args? + if {$gdb_target_name != "sim"} { + # set args + set gdb_args [pref getd gdb/load/$gdb_target_name-opts] + if { $gdb_args != ""} { + debug "set args $gdb_args" + catch {gdb_cmd "set args $gdb_args"} + } + } + + # Run + + if {$auto_start} { + if {[pref get gdb/src/run_run]} { + debug "Runnning target..." + set run run + } else { + debug "Continuing target..." + set run cont + } + if {$gdb_target_name == "exec"} { + set run run + } + if {[catch {gdb_immediate $run} msg]} { + dbug W "msg=$msg" + gdbtk_idle + if {[string match "*help target*" $msg]} { + set_target_name + run_executable $auto_start + return + } + if {[string match "No executable*" $msg]} { + # No executable was specified. Prompt the user for one. + if {[_open_file]} { + run_executable $auto_start + } else { + debug "CANCELLED" + } + return + } + set gdb_running $gdb_running_saved + } else { + debug RUNNING + set gdb_running 1 + } + } else { + SrcWin::point_to_main + } + + gdbtk_update + gdbtk_idle + } elseif {[pref get gdb/mode]} { + # tracepoint -- need to tstart + set gdb_running 1 + tstart + } + return +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_attach_target - attach to the target +# This proc returns the following status messages: +# +# ATTACH_ERROR: An error occurred connecting to target. +# ATTACH_CANCELED: The attach was canceled. +# ATTACH_TARGET_CHANGED: Successfully attached, target changed. +# ATTACH_TARGET_UNCHANGED: Successfully attached, target unchanged. +# UNKNOWN: An unknown error occurred. +# ------------------------------------------------------------------ +proc gdbtk_attach_target {} { + global gdb_loaded + + debug "Attaching...." + set r UNKNOWN + while {1} { + + switch [set_target] { + + ERROR { + # target command failed, ask for a new target name + if {![set_target_name]} { + # canceled again + set r ATTACH_ERROR + break + } + } + + TARGET_CHANGED { + # success -- target changed + set gdb_loaded 0 + set r ATTACH_TARGET_CHANGED + break + } + + CANCELED { + # command cancelled by user + set r ATTACH_CANCELED + break + } + + TARGET_UNCHANGED { + # success -- target NOT changed (i.e., rerun) + set r ATTACH_TARGET_UNCHANGED + break + } + } + } + +# debug "Attach returning: \"$r\"" + return $r +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_step - step the target +# ------------------------------------------------------------------ +proc gdbtk_step {} { + catch {gdb_immediate step} +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_next +# ------------------------------------------------------------------ +proc gdbtk_next {} { + catch {gdb_immediate next} +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_finish +# ------------------------------------------------------------------ +proc gdbtk_finish {} { + catch {gdb_immediate finish} +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_continue +# ------------------------------------------------------------------ +proc gdbtk_continue {} { + catch {gdb_immediate continue} +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_stepi +# ------------------------------------------------------------------ +proc gdbtk_stepi {} { + catch {gdb_immediate stepi} +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_nexti +# ------------------------------------------------------------------ +proc gdbtk_nexti {} { + catch {gdb_immediate nexti} +} + + # ------------------------------------------------------------------ +# PROC: gdbtk_attached +# ------------------------------------------------------------------ +# +# This is called AFTER gdb has successfully done an attach. Use it to +# bring the GUI up to a current state... +proc gdbtk_attached {} { + gdbtk_update +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_detached +# ------------------------------------------------------------------ +# +# This is called AFTER gdb has successfully done an detach. Use it to +# bring the GUI up to a current state... +proc gdbtk_detached {} { + if {!$::gdb_shutting_down} { + run_hooks gdb_no_inferior_hook + } +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_stop +# ------------------------------------------------------------------ +# +# The stop button is tricky. In order to use the stop button, +# the debugger must be able to keep gui alive while target_wait is +# blocking (so that the user can interrupt or detach from it). +# +# The best solution for this is to capture gdb deep down where it +# can block. For _any_ target board, this will be in either +# serial or socket code. These places call ui_loop_hook to +# keep us alive. For native unix, we use an interval timer. +# Simulators either call ui_loop_hook directly (older sims, at least) +# or they call gdb's os_poll_quit callback, where we insert a call +# to ui_loop_hook. Some targets (like v850ice and windows native) +# require a call to ui_loop_hook directly in target_wait. See comments +# before gdb_stop and x_event to find out more about how this is accomplished. +# +# The stop button's behavior: +# Pressing the stop button should attempt to stop the target. If, after +# some time (like 3 seconds), gdb fails to fall out of target_wait (i.e., +# the gui's idle hooks are run), then open a dialog asking the user if +# he'd like to detach. +proc gdbtk_stop {} { + global _gdbtk_stop + + if {$_gdbtk_stop(timer) == ""} { + add_hook gdb_idle_hook gdbtk_stop_idle_callback + set _gdbtk_stop(timer) [after 3000 gdbtk_detach] + catch {gdb_stop} + } +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_stop_idle_callback +# ------------------------------------------------------------------ +# This callback normally does nothing. When the stop button has +# been pressed, though, and gdb has successfully stopped the target, +# this callback will clean up after gdbtk_stop, removing the "Detach" +# dialog (if it's open) and gettingg rid of any outstanding timers +# and hooks. +proc gdbtk_stop_idle_callback {} { + global _gdbtk_stop gdbtk_state + + # Check if the dialog asking if user wants to detach is open + # and unpost it if it exists. + if {$_gdbtk_stop(msg) != ""} { + set ans [list answer $_gdbtk_stop(msg)] + set gdbtk_state($ans) no + } + + if {$_gdbtk_stop(timer) != ""} { + # Cancel the timer callback + after cancel $_gdbtk_stop(timer) + set _gdbtk_stop(timer) "" + catch {remove_hook gdb_idle_hook gdbtk_stop_idle_callback} + } +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_detach +# ------------------------------------------------------------------ +# This proc is installed as a timer event when the stop button +# is pressed. If target_wait doesn't return (we were unable to stop +# the target), then this proc is called. +# +# Open a dialog box asking if the user would like to detach. If so, +# try to detach. If not, do nothing and go away. +proc gdbtk_detach {} { + global _gdbtk_stop + + set _gdbtk_stop(msg) "No response from target. Detach from target\n(and stop debugging it)?" + if {[gdbtk_tcl_query $_gdbtk_stop(msg) no]} { + catch {gdb_stop detach} + } + + set _gdbtk_stop(timer) "" + set _gdbtk_stop(msg) "" + remove_hook gdb_idle_hook gdbtk_stop_idle_callback +} + +# ------------------------------------------------------------------ +# PROC: gdbtk_run +# ------------------------------------------------------------------ +proc gdbtk_run {} { + run_executable +} + +# ------------------------------------------------------------------ +# PROC: set_baud - Tell GDB the baud rate. +# ------------------------------------------------------------------ +proc set_baud {} { + global gdb_target_name + #set target [ide_property get target-internal-name] + set baud [pref getd gdb/load/${gdb_target_name}-baud] + if {$baud == ""} { + set baud [pref get gdb/load/baud] + } +# debug "setting baud to $baud" + catch {gdb_cmd "set remotebaud $baud"} +} + +# ------------------------------------------------------------------ +# PROC: do_state_hook - +# ------------------------------------------------------------------ +proc do_state_hook {varname ind op} { + run_hooks state_hook $varname +} + +# ------------------------------------------------------------------ +# PROC: disconnect - +# ------------------------------------------------------------------ +proc disconnect {{async 0}} { + global gdb_loaded gdb_target_changed + catch {gdb_cmd "detach"} + # force a new target command to do something + set gdb_loaded 0 + set gdb_target_changed 1 + set gdb_running 0 + gdbtk_idle + gdbtk_update + } + +# ------------------------------------------------------------------ +# PROC: tstart - +# ------------------------------------------------------------------ +proc tstart {} { + if {[catch {gdb_cmd "tstart"} errTxt]} { + tk_messageBox -title "Error" -message $errTxt -icon error \ + -type ok + gdbtk_idle + return 0 + } + return 1 +} + +# ------------------------------------------------------------------ +# PROC: tstop - +# ------------------------------------------------------------------ +proc tstop {} { + + if {[catch {gdb_cmd "tstop"} errTxt]} { + tk_messageBox -title "Error" -message $errTxt -icon error \ + -type ok + gdbtk_idle + return 0 + } + return 1 + } + +# ------------------------------------------------------------------ +# PROC: source_file - +# ------------------------------------------------------------------ +proc source_file {} { + set file_name [tk_getOpenFile -title "Choose GDB Command file"] + if {$file_name != ""} { + gdb_cmd "source $file_name" + } +} + + +# ----------------------------------------------------------------------------- +# NAME: gdbtk_signal +# +# SYNOPSIS: gdbtk_signal {name longname} +# +# DESC: This procedure is called from GDB when a signal +# is generated, for example, a SIGSEGV. +# +# ARGS: name - The name of the signal, as returned by +# target_signal_to_name(). +# longname - A description of the signal. +# ----------------------------------------------------------------------------- +proc gdbtk_signal {name {longname ""}} { + dbug W "caught signal $name $longname" + set longname + set message "Program received signal $name, $longname" + set srcs [ManagedWin::find SrcWin] + foreach w $srcs { + $w set_status $message + } + gdbtk_tcl_ignorable_warning signal $message + update idletasks +} + +# Hook for clearing out executable state. Widgets should register a callback +# for this hook if they have anything that may need cleaning if the user +# requests to re-load an executable. +define_hook gdb_clear_file_hook + +# ----------------------------------------------------------------------------- +# NAME: gdbtk_clear_file +# +# SYNOPSIS: gdbtk_clear_file +# +# DESC: This procedure is called when the user requests a new exec +# file load. It runs the gdb_clear_file_hook, which tells +# all widgets to clear state. It CANNOT call gdb_clear_file, +# since this hook runs AFTER we load a new exec file (i.e., +# gdb_clear_file would clear the file name). +# +# ARGS: none +# ----------------------------------------------------------------------------- +proc gdbtk_clear_file {} { + global gdb_target_name + + dbug W "GDBTK_CLEAR_FILE" + # Give widgets a chance to clean up + run_hooks gdb_clear_file_hook + + # Save the target name in case the user has already selected a + # target. No need to force the user to select it again. + set old_target $gdb_target_name + + # Finally, reset our state + initialize_gdbtk + + set gdb_target_name $old_target +} + +# ------------------------------------------------------------------ +# PROC: intialize_gdbtk - (re)initialize gdbtk's state +# ------------------------------------------------------------------ +proc initialize_gdbtk {} { + global gdb_exe_changed gdb_target_changed gdb_running gdb_downloading \ + gdb_loaded gdb_program_has_run file_done gdb_pretty_name gdb_exec \ + gdb_target_cmd download_dialog gdb_pretty_name gdb_exe_name _gdbtk_stop \ + gdb_target_name gdb_target_changed gdbtk_state gdb_kod_cmd gdb_shutting_down + + # initialize state variables + set gdb_exe_changed 0 + set gdb_target_changed 0 + set gdb_running 0 + set gdb_downloading 0 + set gdb_loaded 0 + set gdb_program_has_run 0 + set file_done 0 + set gdb_pretty_name {} + set gdb_exec {} + set gdb_target_cmd "" + set gdb_running 0 + set gdb_shutting_down 0 + + set download_dialog "" + + # gdb_pretty_name is the name of the GDB target as it should be + # displayed to the user. + set gdb_pretty_name "" + + # gdb_exe_name is the name of the executable we are debugging. + set gdb_exe_name "" + + # Initialize readline + if {![info exists gdbtk_state(readline)]} { + # Only do this once... + set gdbtk_state(readline) 0 + set gdbtk_state(console) "" + } + + # check for existence of a kod command and get it's name and + # text for menu entry + set gdb_kod_cmd "" + set msg "" + if {![catch {gdb_cmd "show os"} msg] && ($msg != "")} { + set line1 [string range $msg 0 [expr [string first \n $msg] -1]] + if {[regexp -- \"(.*)\" $line1 dummy cmd]} { + set gdb_kod_cmd $cmd + } + } +# debug "kod_cmd=$gdb_kod_cmd" + + # setup stop button + set _gdbtk_stop(timer) "" + set _gdbtk_stop(msg) "" + + # gdb_target_name is the name of the GDB target; that is, the argument + # to the GDB target command. + set gdb_target_name "" + + # By setting gdb_target_changed, we force a target dialog + # to be displayed on the first "run" + set gdb_target_changed 1 +} + diff --git a/gdb/gdbtk/library/kod.itb b/gdb/gdbtk/library/kod.itb new file mode 100644 index 00000000000..f2770fdf5cf --- /dev/null +++ b/gdb/gdbtk/library/kod.itb @@ -0,0 +1,481 @@ +# Kernel Object Display Window for GDBtk. +# Copyright (C) 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# AUTHOR: Fernando Nasser <fnasser@cygnus.com> +# + + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new process window +# ------------------------------------------------------------------ +body KodWin::constructor {args} { + # + # Create a window with the same name as this object + # + global gdb_kod_cmd + + # initialize local variables + set LevelCmd(0) "info $gdb_kod_cmd " + debug "Level 0 kod command is $LevelCmd(0)" + + gdbtk_busy + build_win + gdbtk_idle + + # Add hooks for this object + add_hook gdb_update_hook [code $this update] + add_hook gdb_busy_hook [code $this busy] + add_hook gdb_idle_hook [code $this idle] + add_hook gdb_set_hook [code $this set_os] +} + +# ------------------------------------------------------------------ +# METHOD: build_win - build the main KOD window +# ------------------------------------------------------------------ +body KodWin::build_win {} { + # FIXME: rename this variable. + global kodActivePane + + debug "Will build KOD window" + + cyg::PanedWindow $itk_interior.pw -orient horizontal + $itk_interior.pw add titlepane + # We would like to use a fixed pane for the buttons. However, + # this feature of PanedWindow doesn't work. + # $itk_interior.pw add buttonpane -resizable 0 + $itk_interior.pw add pane1 + $itk_interior.pw add pane2 + + # Now a frame for what is being listed, headers and list + set tp [$itk_interior.pw childsite titlepane] + Labelledframe $tp.tf -text "No Kernel Objects Known" \ + -anchor nw + set titl $tp.tf + set lf [$tp.tf get_frame] + + set p1 [$itk_interior.pw childsite pane1] + set p2 [$itk_interior.pw childsite pane2] + $p1 configure -height 120 -bd 2 + $p2 configure -height 120 -bd 2 + Labelledframe $p1.d1 -text "Details" -anchor nw + Labelledframe $p2.d2 -text "Details" -anchor nw + set d1 [$p1.d1 get_frame] + set d2 [$p2.d2 get_frame] + pack $p1.d1 $p2.d2 -side top -expand yes -fill both -padx 5 -pady 5 + set pl1 $p1.d1 + set pl2 $p2.d2 + + # Setup the button box + set bf [frame $tp.bf] + set BTop [button $bf.top -height 1 -text Top -command [code $this top]] + set BUp [button $bf.up -height 1 -text Up -command [code $this up]] + set BClear [button $bf.clear -height 1 -text Clear \ + -command [code $this clear]] + set BDisplay [button $bf.display -height 1 -text Display \ + -command [code $this display]] + set kodActivePane pane1 + set BPane1 [radiobutton $bf.pane1 -variable kodActivePane \ + -height 1 -text "Pane 1" -value pane1] + set BPane2 [radiobutton $bf.pane2 -variable kodActivePane \ + -height 1 -text "Pane 2" -value pane2] + balloon register $bf.top "Return to List of Kernel Objects" + balloon register $bf.up "Return to previous List of Objects" + balloon register $bf.clear "Clear Object Detail Panes\nand Active setting" + balloon register $bf.display \ + "Display Object or\nList of Objects of this type" + balloon register $bf.pane1 "Make Pane 1 Active" + balloon register $bf.pane2 "Make Pane 2 Active" + pack $bf.top $bf.up -side left -padx 5 + pack $bf.display $bf.clear -side right -padx 5 + pack $bf.pane2 $bf.pane1 -side bottom -padx 5 -fill both + + # The list of objects + table $lf.s -titlerows 1 \ + -colstretch last -rowstretch last -selectmode single \ + -selecttype row -variable $this \ + -yscrollcommand "$lf.sb set" -resizeborders none \ + -state disabled + scrollbar $lf.sb -orient vertical -command "$lf.s yview" + bind $lf.s <Double-1> [code $this display] + $lf.s tag configure coltag -anchor nw + + grid $lf.s -row 0 -column 0 -sticky nsew + grid $lf.sb -row 0 -column 1 -sticky nsw + grid columnconfigure $lf 0 -weight 1 + grid rowconfigure $lf 0 -weight 1 + + # Areas to display object details + set t1 [table $d1.t1 -titlerows 1 -colstretch last -rowstretch last \ + -selectmode single -selecttype row -variable $this-pane1 \ + -yscrollcommand "$d1.s1 set" -resizeborders none \ + -rows 1 -cols 1 -state disabled] + scrollbar $d1.s1 -orient vertical -command "$d1.t1 yview" + set t2 [table $d2.t2 -titlerows 1 -colstretch last -rowstretch last \ + -selectmode single -selecttype row -variable $this-pane2 \ + -yscrollcommand "$d2.s2 set" -resizeborders none \ + -rows 1 -cols 1 -state disabled] + scrollbar $d2.s2 -orient vertical -command "$d2.t2 yview" + + grid $d1.t1 -row 0 -column 0 -sticky nsew + grid $d1.s1 -row 0 -column 1 -sticky nsw + grid columnconfigure $d1 0 -weight 1 + grid rowconfigure $d1 0 -weight 1 + grid $d2.t2 -row 0 -column 0 -sticky nsew + grid $d2.s2 -row 0 -column 1 -sticky nsw + grid columnconfigure $d2 0 -weight 1 + grid rowconfigure $d2 0 -weight 1 + + debug "Will pack KOD window" + pack $tp.tf -side top -expand yes -fill both -padx 5 -pady 5 + pack $tp.bf -side top -expand no -fill x -padx 5 -pady 5 + pack $itk_interior.pw -side bottom -expand yes -fill both + wm minsize $Top 450 500 + + # Initialize button state variables for idle (called before update) + set BState(BDisplay) disabled + set BState(BClear) disabled + set BState(BTop) disabled + set BState(BUp) disabled + + # window_name "Kernel Objects" + + update +} + +# ------------------------------------------------------------------ +# METHOD: update - update widget when something changes +# ------------------------------------------------------------------ +body KodWin::update {} { + + debug "updating kod window" + + _disable_buttons + + display_list + display_object + + _restore_buttons + +} + +# ------------------------------------------------------------------ +# METHOD: display - update the display based on the selection +# it can be a list or an actual object +# We get here from a press on the Display button or +# from a <Double-1> on a line of the list of objects +# ------------------------------------------------------------------ +body KodWin::display {} { + upvar \#0 $this table_vals + if {!$Running && [$lf.s cget -rows] > 1} { + gdbtk_busy + set linenum [$lf.s index active row] + set object $table_vals($linenum,0) + debug "display selection on line $linenum $object" + incr level + set LevelCmd($level) $LevelCmd([expr $level-1]) + append LevelCmd($level) $object + debug "kod command for level $level is now: $LevelCmd($level)" + update + # Run idle hooks and cause all other widgets to update + gdbtk_idle + } +} + +# ------------------------------------------------------------------ +# METHOD: display_list - display list of objects +# ------------------------------------------------------------------ +body KodWin::display_list {} { + upvar \#0 $this table_vals + + debug "displaying list of objects" + + $lf.s configure -state normal + set cmd $LevelCmd($level) + debug "new kod command is $cmd" + if {[catch "gdb_cmd \"$cmd\"" objects]} { + # failed. leave window blank + $titl configure -text "Kernel Object Display Failed" + $lf.s delete rows 0 [$lf.s index end row] + $lf.s configure -state disabled + set BState(BDisplay) disabled + return + } + + debug "KodWin update: \n$objects" + if {[llength $objects] == 0} { + $titl configure -text "No Kernel Objects Known" + # no objects listed. + $lf.s delete rows 0 [$lf.s index end row] + $lf.s configure -state disabled + set BState(BDisplay) disabled + return + } + + # insert each line one at a time + set num_lines -1 + foreach line [split $objects \n] { + if {$num_lines == -1} { + if {![string match List* $line]} { + if {($level > 0)} { + display_object $cmd objects + incr level -1 + $lf.s configure -state disabled + return + } else { + # if level 0 first line does not start with List ignore it + $titl configure -text "List of Kernel Objects" + } + } else { + $titl configure -text $line + } + # Clear listbox and headers to get new stuff. + $lf.s delete rows 0 [$lf.s index end row] + } elseif {$line == ""} { + break + } else { + set col 0 + set list [split [string trim $line] \t] + if {$num_lines == 0} { + $lf.s configure -cols [llength $list] -titlerows 1 + } + foreach item $list { + debug "inserting $item at $num_lines,$col" + set table_vals($num_lines,$col) $item + incr col + } + } + incr num_lines + } + $lf.s configure -rows [expr {$num_lines + 1}] + + if {$num_lines > 0} { + set BState(BDisplay) active + } + + if {$level == 0} { + set BState(BTop) disabled + set BState(BUp) disabled + } else { + set BState(BTop) active + set BState(BUp) active + } + + $lf.s configure -state disabled + $lf.s see 0,0 + $lf.s activate 1,0 + + _restore_buttons +} + +# ------------------------------------------------------------------ +# METHOD: display_object - display information about an object +# When called from update we have to reissue the gdb +# command to get fresh data +# ------------------------------------------------------------------ +body KodWin::display_object {{cmd ""} {obj ""}} { + debug "Displaying object details..." + upvar $obj objects + global kodActivePane + debug "Active Pane is $kodActivePane" + + # Determine which frame to use + if {$kodActivePane == "pane2"} { + set curpan $t2 + upvar \#0 $this-pane2 pane_values + if {$cmd != ""} { + # save command for update + set pane2command $cmd + } else { + # reuse saved command + set cmd $pane2command + } + } else { + set curpan $t1 + upvar \#0 $this-pane1 pane_values + if {$cmd != ""} { + # save command for update + set pane1command $cmd + } else { + # reuse saved command + set cmd $pane1command + } + } + debug "curpan $curpan" + + # here we must take care of the case where the user has activated a window + # but it does not have been filled yet. We just return. + if {$cmd == ""} { + return + } + + $curpan configure -state normal + $curpan delete rows 0 [$curpan index end row] + if {$obj == ""} { + debug "pane kod command is $cmd" + if {[catch "gdb_cmd \"$cmd\"" objects] + || $objects == ""} { + # Failed. Tell user object no longer there. + $curpan configure -state disabled + return + } + } + + set num_lin 0 + foreach line [split $objects \n] { + set col 0 + set list [split [string trim $line] \t] + if {$num_lin == 0} { + $curpan configure -cols [llength $list] + } + foreach item $list { + set pane_values($num_lin,$col) $item + incr col + } + incr num_lin + } + $curpan configure -rows $num_lin -state disabled +} + +# ------------------------------------------------------------------ +# METHOD: clear - clear detail panes and reset pane selection +# ------------------------------------------------------------------ +body KodWin::clear {} { + debug "going to clear detail panes and pane selection" + $t1 configure -state normal + $t2 configure -state normal + $t1 delete rows 0 [$t1 index end row] + $t2 delete rows 0 [$t2 index end row] + $t1 configure -state disabled + $t2 configure -state disabled + # Default to pane 1 again. + global kodActivePane + set kodActivePane pane1 + set pane1command "" + set pane2command "" +} + +# ------------------------------------------------------------------ +# METHOD: top - go to the list of types of objects (top level) +# ------------------------------------------------------------------ +body KodWin::top {} { + debug "going to top from level $level" + if {$level > 0} { + set level 0 + update + } +} + +# ------------------------------------------------------------------ +# METHOD: up - go to the list of objects which led to the current one +# ------------------------------------------------------------------ +body KodWin::up {} { + debug "going up from level $level..." + if {$level > 0} { + incr level -1 + debug "...to level $level" + update + } +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body KodWin::destructor {} { + upvar \#0 $this table_vals $this-pane1 pane1_vals $this-pane2 pane2_vals + global kodActivePane + + catch {unset table_vals} + catch {unset pane1_vals} + catch {unset pane2_vals} + catch {unset kodActivePane} + + remove_hook gdb_update_hook [code $this update] + remove_hook gdb_idle_hook [code $this idle] + remove_hook gdb_busy_hook [code $this busy] + remove_hook gdb_set_hook [code $this set_os] +} + +# ------------------------------------------------------------------ +# METHOD: set - called when user runs `set os' command +# ------------------------------------------------------------------ +body KodWin::set_os {var value} { + if {$var == "os" && $value != ""} { + set LevelCmd(0) "info $value " + set level 0 + update + } +} + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body KodWin::reconfig {} { + destroy $itk_interior.bf + destroy $titl + build_win +} + +# ------------------------------------------------------------------ +# METHOD: busy - gdb_busy_hook +# +# This method should accomplish blocking +# - clicks in the window +# - change mouse pointer +# ------------------------------------------------------------------ +body KodWin::busy {} { + set Running 1 + _disable_buttons + cursor watch +} + +# ------------------------------------------------------------------ +# METHOD: idle - idle hook. Run when the target is not running +# ------------------------------------------------------------------ +body KodWin::idle {} { + set Running 0 + _restore_buttons + cursor {} +} + +# ------------------------------------------------------------------ +# METHOD: cursor - set the window cursor +# This is a convenience method which simply sets the mouse +# pointer to the given glyph. +# ------------------------------------------------------------------ +body KodWin::cursor {glyph} { + $Top configure -cursor $glyph +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: _disable_buttons - disable all buttons +# Used when we are busy and can't take another event +# ------------------------------------------------------------------ +body KodWin::_disable_buttons {} { + $BTop configure -state disabled + $BUp configure -state disabled + $BDisplay configure -state disabled + $BClear configure -state disabled +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: _restore_buttons - restore all buttons to their +# previous states. +# Used when we are busy and can't take another event +# ------------------------------------------------------------------ +body KodWin::_restore_buttons {} { + $BTop configure -state $BState(BTop) + $BUp configure -state $BState(BUp) + $BDisplay configure -state $BState(BDisplay) + # CLEAR is always active, except when busy + $BClear configure -state active +} diff --git a/gdb/gdbtk/library/kod.ith b/gdb/gdbtk/library/kod.ith new file mode 100644 index 00000000000..d66167007fc --- /dev/null +++ b/gdb/gdbtk/library/kod.ith @@ -0,0 +1,59 @@ +# Kernel Object Display Window definition for GDBtk. +# Copyright (C) 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +class KodWin { + inherit EmbeddedWin GDBWin + + private { + variable bf + variable lf + variable titl + variable BTop + variable BUp + variable BClear + variable BDisplay + variable lb + variable t1 + variable t2 + variable pl1 + variable pl2 + variable pane1command "" + variable pane2command "" + variable BPane1 + variable BPane2 + variable level 0 + common LevelCmd + variable BState + variable Running 0 + method build_win {} + method update {} + method display {} + method display_list {} + method display_object {{cmd ""} {obj ""}} + method clear {} + method top {} + method up {} + method busy {} + method idle {} + method cursor {glyph} + method _disable_buttons {} + method _restore_buttons {} + method set_os {var value} + } + + public { + method constructor {args} + method destructor {} + method reconfig {} + } +} diff --git a/gdb/gdbtk/library/locals.tcl b/gdb/gdbtk/library/locals.tcl new file mode 100644 index 00000000000..50bd9aeced3 --- /dev/null +++ b/gdb/gdbtk/library/locals.tcl @@ -0,0 +1,123 @@ +# Local variable window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class LocalsWin { + inherit VariableWin + + # ------------------------------------------------------------------ + # CONSTRUCTOR - create new locals window + # ------------------------------------------------------------------ + constructor {args} { + update + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - delete locals window + # ------------------------------------------------------------------ + destructor { + } + + method build_win {f} { + global tcl_platform + build_menu_helper Variable + if {$tcl_platform(platform) == "windows"} { + frame $f.f + VariableWin::build_win $f.f + pack $f.f -expand yes -fill both -side top + frame $f.stat + pack $f.stat -side bottom -fill x + } else { + VariableWin::build_win $f + } + } + + + # ------------------------------------------------------------------ + # METHOD: reconfig + # Overrides VarialbeWin::reconfig method. Have to make sure the locals + # will get redrawn after everything is destroyed... + # ------------------------------------------------------------------ + method reconfig {} { + VariableWin::reconfig + populate {} + } + + # ------------------------------------------------------------------ + # METHOD: getVariablesBlankPath + # Overrides VarialbeWin::getVariablesBlankPath. For a Locals Window, + # this method returns a list of local variables. + # ------------------------------------------------------------------ + method getVariablesBlankPath {} { + global Update + debug "LocalsWin::getVariablesBlankPath" + + return [$_frame variables] + } + + method update {} { + global Update Display + + debug "START LOCALS UPDATE CALLBACK" + # Check that a context switch has not occured + if {[context_switch]} { + debug "CONTEXT SWITCH" + + # our context has changed... repopulate with new variables + # destroy the old tree and create a new one + # + # We need to be more intelligent about saving window state + # when browsing the stack or stepping into new frames, but + # for now, we'll have to settle for just getting this working. + deleteTree + set ChangeList {} + + # context_switch will have already created the new frame for + # us, so all we need to do is shove stuff into the window. + debug "_frame=$_frame" + if {$_frame != ""} { + debug "vars=[$_frame variables]" + } + if {$_frame != "" && [$_frame variables] != ""} { + populate {} + } + } + + # Erase old variables + if {$_frame != ""} { + foreach var [$_frame old] { + $Hlist delete entry $var + $_frame deleteOld + unset Update($this,$var) + } + + # Add new variables + foreach var [$_frame new] { + set Update($this,$var) 1 + $Hlist add $var \ + -itemtype text \ + -text [label $var] + if {[$var numChildren] > 0} { + # Make sure we get this labeled as openable + $Tree setmode $var open + } + } + } + + # Update variables in window + VariableWin::update + + debug "END LOCALS UPDATE CALLBACK" + } +} + diff --git a/gdb/gdbtk/library/main.tcl b/gdb/gdbtk/library/main.tcl new file mode 100644 index 00000000000..7b18e5ab2c3 --- /dev/null +++ b/gdb/gdbtk/library/main.tcl @@ -0,0 +1,156 @@ +# GDBtk (Insight) entry point +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# State is controlled by 5 global boolean variables. +# +# gdb_target_changed +# gdb_exe_changed +# gdb_running +# gdb_downloading +# gdb_loaded + +################### Initialization code ######################### + +# If GDBtk fails to start at all, you might want to uncomment one or +# both of these. +#set tcl_traceExec 2 +#set tcl_traceCompile 1 + +# Add gdb's Tcl library directory to the end of the auto-load search path, if +# it isn't already on the path: +# Note: GDBTK_LIBRARY will be set in tcl_findLibrary before main.tcl is called. + +if {[info exists auto_path]} { + if {[lsearch -exact $auto_path $GDBTK_LIBRARY] < 0} { + lappend auto_path $GDBTK_LIBRARY + } +} + +# Require the packages we need. Most are loaded already, but this will catch +# any odd errors... : +package require Tcl 8.0 +package require Tk 8.0 +package require Itcl 3.0 +package require Itk 3.0 +package require Gdbtk 1.0 +package require combobox 1.0 + +namespace import itcl::* + +namespace import debug::* + +if {![find_iwidgets_library]} { + tk_messageBox -title Error -message "Could not find the Iwidgets libraries. +Got nameofexec: [info nameofexecutable] +Error(s) were: \n$errMsg" \ + -icon error -type ok + exit +} + +# Environment variables controlling debugging: +# GDBTK_TRACE +# unset or 0 no tracing +# 1 tracing initialized but not started +# 2 tracing initialized and started +# +# GDBTK_DEBUGFILE - filename to write debugging messages and +# trace information (if tracing is enabled). +# +if {[info exists env(GDBTK_TRACE)] && $env(GDBTK_TRACE) != 0} { + # WARNING: the tracing code must not trace into itself or + # infinite recursion will result. As currently configured + # the tracing code will not trace basic tcl functions or anything defined + # before debug::init. For this reason we must source the DebugWin + # code before debug::init is called. + source [file join $GDBTK_LIBRARY debugwin.ith] + source [file join $GDBTK_LIBRARY debugwin.itb] + + # Calling this installs our hooks for tracing and profiling. + # This WILL slow things down. + ::debug::init + + if {$env(GDBTK_TRACE) == 2} { + ::debug::trace_start + } +} + +if {[info exists env(GDBTK_DEBUGFILE)]} { + ::debug::logfile $env(GDBTK_DEBUGFILE) +} + +if {$tcl_platform(platform) == "unix"} { +# tix resetoptions TK TK +# tk_setPalette tan + tix resetoptions TixGray [tix cget -fontset] +} + +# initialize state variables +initialize_gdbtk + +# set traces on state variables +trace variable gdb_running w do_state_hook +trace variable gdb_downloading w do_state_hook +trace variable gdb_loaded w do_state_hook +define_hook state_hook + +# set up preferences +pref init + +# let libgui tell us how to feel +standard_look_and_feel + +# now let GDB set its default preferences +pref_set_defaults + +# read in preferences +pref_read + +init_disassembly_flavor + +ManagedWin::init + +# This stuff will help us play nice with WindowMaker's AppIcons. +# Can't do the first bit yet, since we don't get this from gdb... +# wm command . [concat $argv0 $argv] +wm group . . + +# Open debug window if testsuite is not running and GDBTK_DEBUG is set +if {![info exists env(GDBTK_TEST_RUNNING)] || !$env(GDBTK_TEST_RUNNING)} { + if {[info exists env(GDBTK_DEBUG)] && $env(GDBTK_DEBUG) > 1} { + ManagedWin::open DebugWin + } +} + +# some initial commands to get gdb in the right mode +gdb_cmd {set height 0} +gdb_cmd {set width 0} + +if {[info exists env(GDBTK_TEST_RUNNING)] && $env(GDBTK_TEST_RUNNING)} { + set gdb_target_name "exec" +} else { + # gdb_target_name is the name of the GDB target; that is, the argument + # to the GDB target command. + set gdb_target_name "" + # By setting gdb_target_changed, we force a target dialog + # to be displayed on the first "run" + set gdb_target_changed 1 +} + +update + +# Uncomment the next line if you want a splash screen at startup... +# ManagedWin::open About -transient -expire 5000 + +gdbtk_idle + diff --git a/gdb/gdbtk/library/managedwin.itb b/gdb/gdbtk/library/managedwin.itb new file mode 100644 index 00000000000..3dbb635b28d --- /dev/null +++ b/gdb/gdbtk/library/managedwin.itb @@ -0,0 +1,267 @@ +# Managed window for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +body ManagedWin::reconfig {} {} + + +body ManagedWin::window_name {wname {iname ""}} { + set top [winfo toplevel [namespace tail $this]] + wm title $top $wname + if {$iname != ""} { + wm iconname $top $iname + } else { + wm iconname $top $wname + } +} + + +body ManagedWin::reveal {} { + # Do this update to flush all changes before deiconifying the window. + update idletasks + + set top [winfo toplevel [namespace tail $this]] + wm deiconify $top + + # I don't understand this next line and no one commented it, so it's gone. + #focus -force [focus -lastfor $top] + + focus $top + raise $top +} + +body ManagedWin::restart {} { + # This is needed in case we've called "gdbtk_busy" before the restart. + # This will configure the stop/run button as necessary + after idle gdbtk_idle + + # call the reconfig method for each object + foreach obj $manage_active { + if {[catch {$obj reconfig} msg]} { + dbug W "reconfig failed for $obj - $msg" + } + } +} + +body ManagedWin::open_dlg {class args} { + + set newwin [eval _open $class $args] + if {$newwin != ""} { + $newwin reveal + $newwin post + } +} + + +body ManagedWin::open {class args} { + + set newwin [eval _open $class $args] + if {$newwin != ""} { + if {[$newwin isa ModalDialog]} { + after idle "$newwin reveal; $newwin post" + } else { + after idle "$newwin reveal" + } + } + + return $newwin +} + +body ManagedWin::_open { class args } { + debug "$class $args" + + parse_args force + + if {!$force} { + # check all windows for one of this type + foreach obj $manage_active { + if {[$obj isa $class]} { + $obj reveal + return $obj + } + } + + } + # need to create a new window + return [eval _create $class $args] +} + +body ManagedWin::_create { class args } { + + set win [string tolower $class] + debug "win=$win args=$args" + + parse_args {center transient {over ""}} + + # increment window numbers until we get an unused one + set i 0 + while {[winfo exists .$win$i]} { incr i } + + while { 1 } { + set top [toplevel .$win$i] + wm withdraw $top + wm protocol $top WM_DELETE_WINDOW "destroy $top" + wm group $top . + set newwin $top.$win + if {[catch {uplevel \#0 eval $class $newwin $args} msg]} { + dbug E "object creation of $class failed: $msg" + dbug E $::errorInfo + if {[string first "object already exists" $msg] != -1} { + # sometimes an object is still really around even though + # [winfo exists] said it didn't exist. Check for this case + # and increment the window number again. + catch {destroy $top} + incr i + } else { + return "" + } + } else { + break + } + } + + if {[catch {pack $newwin -expand yes -fill both}]} { + dbug W "packing of $newwin failed: $::errorInfo" + return "" + } + + wm maxsize $top $screenwidth $screenheight + wm minsize $top 20 20 + + if {$over != ""} { + # center new window over widget + set t [winfo toplevel [namespace tail $over]] + set cx [expr {[winfo rootx $t] + [winfo width $t] / 2}] + set cy [expr {[winfo rooty $t] + [winfo height $t] / 2}] + set x [expr {$cx - [winfo reqwidth $top] / 2}] + set y [expr {$cy - [winfo reqheight $top] / 2}] + wm geometry $top +$x+$y + } elseif {$center} { + # center the window on the screen + set x [expr {[winfo screenwidth $top] / 2 - [winfo reqwidth $top] / 2}] + set y [expr {[winfo screenheight $top] / 2 - [winfo reqheight $top] / 2}] + wm geometry $top +$x+$y + } + + if {$transient} { + wm resizable $top 0 0 + wm transient $top . + } elseif {$::tcl_platform(platform) == "unix"} { + # Modal dialogs DONT get Icons... + if {[pref get gdb/use_icons] && ![$newwin isa ModalDialog]} { + set icon [make_icon_window ${top}_icon] + wm iconwindow $top $icon + bind $icon <Double-1> "$newwin reveal" + } + } + + if {[info exists ::env(GDBTK_TEST_RUNNING)] && $::env(GDBTK_TEST_RUNNING)} { + set g "+100+100" + wm geometry $top $g + wm positionfrom $top user + } else { + set g [pref getd gdb/geometry/$newwin] + if {$g == "1x1+0+0"} { + dbug E "bad geometry" + set g "" + } + if {$g != ""} { + # OK. We have a requested geometry. We know that it fits on the screen + # because we set the maxsize. Now we have to make sure it will not be + # displayed off the screen. + set w 0; set h 0; set x 0; set y 0 + if {![catch {scan $g "%dx%d%d%d" w h x y} res]} { + if {$x < 0} { + set x [expr $screenwidth + $x] + } + if {$y < 0} { + set y [expr $screenheight + $y] + } + + # If the window is transient, then don't reset its size, since + # the user didn't set this anyway, and in some cases where the + # size can change dynamically, like the Global Preferences + # dialog, this can hide parts of the dialog with no recourse... + + # if dont_remember_size is true, don't set size, just like + # transients + + if {$transient || [dont_remember_size]} { + set g "+${x}+${y}" + } else { + set g "${w}x${h}+${x}+${y}" + } + if {[expr $x+50] < $screenwidth && [expr $y+20] < $screenheight} { + wm geometry $top $g + wm positionfrom $top user + } + } + } + } + + bind $top <Alt-F4> [list delete object $newwin] + + return $newwin +} + +body ManagedWin::find { win } { + debug "$win" + set res "" + foreach obj $manage_active { + if {[$obj isa $win]} { + lappend res $obj + } + } + return $res +} + +body ManagedWin::enable { on } { +} + + +body ManagedWin::init {} { + debug + wm withdraw . + set screenheight [winfo screenheight .] + set screenwidth [winfo screenwidth .] +} + +body ManagedWin::destroy_toplevel {} { + after idle "update idletasks;destroy $Top" +} + +body ManagedWin::freeze_me {} { + $Top configure -cursor watch + ::update idletasks +} + +body ManagedWin::thaw_me {} { + + $Top configure -cursor {} + ::update idletasks +} + +# ------------------------------------------------------------------ +# make_icon_window - create a small window with an icon in +# it for use by certain Unix window managers. +# ------------------------------------------------------------------ + +body ManagedWin::make_icon_window {name {file "gdbtk_icon"}} { + if {![winfo exists $name]} { + toplevel $name + label $name.im -image \ + [image create photo icon_photo -file [file join $::gdb_ImageDir $file.gif]] + } + pack $name.im + return $name +} diff --git a/gdb/gdbtk/library/managedwin.ith b/gdb/gdbtk/library/managedwin.ith new file mode 100644 index 00000000000..a25cee41e9a --- /dev/null +++ b/gdb/gdbtk/library/managedwin.ith @@ -0,0 +1,102 @@ +# Managed window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class ManagedWin { + inherit itk::Widget + + public { + method reconfig {} + method destroy_toplevel {} + method quit_if_last {} {return 1} + method enable {on} + method reveal {} + method window_name {wname {iname ""}} + + variable nosize 0 + + proc find {win} + proc open {args} + proc open_dlg {class args} + proc init {} + proc restart {} + } + + protected { + proc dont_remember_size {} { + return 0 + } + method freeze_me {} + method thaw_me {} + + variable Top + } + + private { + proc _create {class args} + proc _open {class args} + proc make_icon_window {name {file "gdbtk_icon"}} + } + + protected { + # manage_active - list of active window objects + common manage_active "" + + # this is the counter of TopLevelWins open + # when it hits 0, exit. + common numTopWins 0 + + common screenwidth + common screenheight + common mainwindow + } + + constructor {args} { + debug "$this args=$args" + lappend manage_active $this + set Top [winfo toplevel $itk_interior] + + } + + destructor { + + set infoList [after info] + + # remove object from list + set i [lsearch -exact $manage_active $this] + if {$i != -1} { + set manage_active [lreplace $manage_active $i $i] + } + + # save geometry + set g [wm geometry [winfo toplevel [namespace tail $this]]] + pref setd gdb/geometry/[namespace tail $this] $g + + # If no toplevels remain, quit. However, check the quit_if_last + # flag since we might be doing something like displaying a + # splash screen at startup... + + if {!$numTopWins && [quit_if_last]} { + # save window positions of remaining windows + foreach obj $manage_active { + set g [wm geometry [winfo toplevel [namespace tail $obj]]] + pref setd gdb/geometry/[namespace tail $obj] $g + } + pref_save + gdb_force_quit + } else { + destroy_toplevel + } + } + +} diff --git a/gdb/gdbtk/library/mempref.itb b/gdb/gdbtk/library/mempref.itb new file mode 100644 index 00000000000..74be3a925fc --- /dev/null +++ b/gdb/gdbtk/library/mempref.itb @@ -0,0 +1,385 @@ +# Memory display preferences window for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ------------------------------------------------------------------ +# METHOD: constructor - build the dialog +# ------------------------------------------------------------------ +body MemPref::constructor {args} { + + window_name "Memory Preferences" + + eval itk_initialize $args + + if {$float_size == ""} { + set float_size [gdb_eval sizeof(float)] + set double_size [gdb_eval sizeof(double)] + } + + if {[string compare $format f] == 0} { + set gformat x + set format_disabled 1 + if {$size == $float_size} { + set gsize 3 + } elseif {$size == $double_size} { + set gsize 5 + } + } else { + set gsize $size + set gformat $format + } + + set gnumbytes $numbytes + set gbpr $bpr + set gascii $ascii + set gascii_char $ascii_char + + build_win + + if {$format_disabled} { + set format_disabled 0 + disable_format + } + + wm resizable [winfo toplevel $itk_interior] 0 0 +} + +# ------------------------------------------------------------------ +# METHOD: destructor - destroy the dialog +# ------------------------------------------------------------------ +body MemPref::destructor {} { + trace vdelete [scope gnumbytes] w [code $this check_numbytes] +} + +# ------------------------------------------------------------------ +# METHOD: build_win - build the dialog +# ------------------------------------------------------------------ +body MemPref::build_win {} { + + frame $itk_interior.f + set f [frame $itk_interior.f.a] + frame $itk_interior.f.b + + # SIZE + Labelledframe $f.f1 -anchor nw -text Size + set fr [$f.f1 get_frame] + + set Widgets(rb-Byte) [radiobutton $fr.1 -variable [scope gsize] -text Byte \ + -value 1 -command [code $this enable_format]] + set Widgets(rb-half_word) [radiobutton $fr.2 -variable [scope gsize] -text "Half Word" \ + -value 2 -command [code $this enable_format]] + set Widgets(rb-word) [radiobutton $fr.4 -variable [scope gsize] -text Word \ + -value 4 -command [code $this enable_format]] + set Widgets(rb-d_word) [radiobutton $fr.8 -variable [scope gsize] -text "Double Word" \ + -value 8 -command [code $this enable_format]] + set Widgets(rb-float) [radiobutton $fr.f -variable [scope gsize] -text Float \ + -value 3 -command [code $this disable_format]] + set Widgets(rb-d_float) [radiobutton $fr.d -variable [scope gsize] -text "Double Float" \ + -value 5 -command [code $this disable_format]] + grid $fr.1 $fr.4 $fr.f -sticky w -padx 4 + grid $fr.2 $fr.8 $fr.d -sticky w -padx 4 + + # FORMAT + Labelledframe $f.f2 -anchor nw -text Format + set fr [$f.f2 get_frame] + set Widgets(rb-binary) [radiobutton $fr.1 -variable [scope gformat] \ + -text Binary -value t] + set Widgets(rb-octal) [radiobutton $fr.2 -variable [scope gformat] \ + -text Octal -value o] + set Widgets(rb-hex) [radiobutton $fr.3 -variable [scope gformat] \ + -text Hex -value x] + set Widgets(rb-signed_dec) [radiobutton $fr.4 -variable [scope gformat] \ + -text "Signed Decimal" -value d] + set Widgets(rb-unsign_dec) [radiobutton $fr.5 -variable [scope gformat] \ + -text "Unsigned Decimal" -value u] + + grid $fr.1 $fr.2 $fr.3 -sticky w -padx 4 + grid $fr.4 $fr.5 x -sticky w -padx 4 + + # TOTAL BYTES + Labelledframe $f.fx -anchor nw -text "Number of Bytes" + + if {$gnumbytes == 0} { + set gnumbytes $default_numbytes + set gvar 0 + } else { + set gvar 1 + } + + set fr [$f.fx get_frame] + set Widgets(rb-win_size) [radiobutton $fr.1 -variable [scope gvar] -text "Depends on window size" \ + -value 0 -command [code $this toggle_size_control]] + frame $fr.2 + set Widgets(rb-fixed) [radiobutton $fr.2.b -variable [scope gvar] -text Fixed \ + -value 1 -command [code $this toggle_size_control]] + + set old_numbytes $default_numbytes + set Widgets(e-numbytes) [entry $fr.2.e -textvariable [scope gnumbytes] -width 3] + set normal_background [$Widgets(e-numbytes) cget -background] + + # + # Trace gnumbytes so it will always be a +'ve integer... Have to set this + # trace AFTER the widget's textvariable is set so this trace will fire + # BEFORE the widget's trace. + # + + trace variable [scope gnumbytes] w [code $this check_numbytes] + + label $fr.2.l -text bytes + grid $fr.2.b $fr.2.e $fr.2.l -sticky we + grid $fr.1 x -sticky w -padx 4 + grid $fr.2 x -sticky w -padx 4 + grid columnconfigure $fr 1 -weight 1 + + # MISC + Labelledframe $f.1 -anchor nw -text "Miscellaneous" + set fr [$f.1 get_frame] + frame $fr.1 + label $fr.1.plabel -height 1 -width 1 -bg $color -relief raised + set Widgets(b-color) [button $fr.1.pc -text "Change color..." \ + -command [code $this pick $fr.1.plabel]] + grid $fr.1.plabel $fr.1.pc + frame $fr.2 + label $fr.2.l -text "Bytes Per Row " + set Widgets(b-bytes_per_row) [::combobox::combobox $fr.2.c \ + -command [code $this set_bytes_per_row] \ + -width 4 -editable 0 -font src-font] + $fr.2.c list insert end 4 + $fr.2.c list insert end 8 + $fr.2.c list insert end 16 + $fr.2.c list insert end 32 + $fr.2.c list insert end 64 + $fr.2.c list insert end 128 + $fr.2.c configure -value 16 + + pack $fr.2.l -side left -anchor e + pack $fr.2.c -side right + + set Widgets(cb-display_ascii) [checkbutton $fr.3 -variable [scope gascii] -text "Display ASCII"] + frame $fr.4 + set Widgets(e-ascii_char) [entry $fr.4.e -textvariable [scope gascii_char] -width 1] + label $fr.4.l -text "Control Char" + grid $fr.4.e $fr.4.l -sticky we + grid $fr.2 x $fr.3 -sticky w -padx 4 + grid $fr.4 -sticky w -padx 4 + grid columnconfigure $fr 1 -weight 1 + + grid $f.f1 -padx 5 -pady 6 -sticky news + grid $f.f2 -padx 5 -pady 6 -sticky news + grid $f.fx -padx 5 -pady 6 -sticky news + grid $f.1 -padx 5 -pady 6 -sticky we + + + set Widgets(b-ok) [button $itk_interior.f.b.ok -text OK -command [code $this ok] -width 7 -default active] + focus $Widgets(b-ok) + + # If there is an OK button, set Return in the entry field to invoke it... + + bind $Widgets(e-numbytes) <KeyPress-Return> "$Widgets(b-ok) flash ; $Widgets(b-ok) invoke" + + set Widgets(b-cancel) [button $itk_interior.f.b.quit -text Cancel -command [code $this cancel] -width 7] + set Widgets(b-apply) [button $itk_interior.f.b.apply -text Apply -command [code $this apply] -width 7] + standard_button_box $itk_interior.f.b + + grid $itk_interior.f.a + grid $itk_interior.f.b -sticky news + grid $itk_interior.f + + # + # Set the state of the window size entry here... + # + toggle_size_control + +} + +# ------------------------------------------------------------------ +# METHOD: busy - make the widget unusable +# ------------------------------------------------------------------ +body MemPref::busy {} { + set top [winfo toplevel $itk_interior] + $top configure -cursor watch + + # Disable all the radiobuttons and what not + foreach w [array names Widgets] { + set WidgetState($w) [$Widgets($w) cget -state] + } + foreach w [array names Widgets] { + $Widgets($w) configure -state disabled + } +} + +# ------------------------------------------------------------------ +# METHOD: idle - make the widget useable +# ------------------------------------------------------------------ +body MemPref::idle {} { + set top [winfo toplevel $itk_interior] + $top configure -cursor {} + + # Re-enable all widgets + foreach w [array names Widgets] { + $Widgets($w) configure -state $WidgetState($w) + } +} +# ------------------------------------------------------------------ +# METHOD: ok - apply and quit +# ------------------------------------------------------------------ +body MemPref::ok {} { + apply + unpost +} + +# ------------------------------------------------------------------ +# METHOD: cancel - just close the dialog w/o saving changes +# ------------------------------------------------------------------ +body MemPref::cancel {} { + unpost +} + +# ------------------------------------------------------------------ +# METHOD: check_numbytes - a trace to make sure gnumbytes is an int > 0 +# ------------------------------------------------------------------ +body MemPref::check_numbytes {var index mode} { + upvar \#0 $var true + if {($true != "") && ([catch {expr {(int($true) != double($true)) || $true <= 0}} val] + || $val)} { + bell + set true $old_numbytes + } else { + set old_numbytes $true + } +} + +# ------------------------------------------------------------------ +# METHOD: set_bytes_per_row - combobox callback to set the bytes per row +# ------------------------------------------------------------------ +body MemPref::set_bytes_per_row {w value} { + set gbpr $value +} + +# ------------------------------------------------------------------ +# METHOD: toggle_size_control - toggle the state of the entry box as the +# control method changes +# ------------------------------------------------------------------ +body MemPref::toggle_size_control {} { + + if {$gvar} { + $Widgets(e-numbytes) configure -state normal \ + -background $normal_background + } else { + $Widgets(e-numbytes) configure -state disabled -background lightgray + if {[info exists Widgets(b-ok)]} { + focus $Widgets(b-ok) + } + } +} + +# ------------------------------------------------------------------ +# METHOD: apply - apply changes to the parent window +# ------------------------------------------------------------------ +body MemPref::apply {} { + + busy + gdbtk_busy + + if {$gvar == 0} { + set numbytes 0 + } elseif {$gnumbytes == "" || $gnumbytes == 0} { + # Protect against the case where someone sets the + # entry field to an empty string, or pastes in a 0... + bell + set gnumbytes $default_numbytes + set numbytes $gnumbytes + } else { + set numbytes $gnumbytes + } + switch $gsize { + 3 { + set size $float_size + set format f + } + 5 { + set size $double_size + set format f + } + default { + set size $gsize + set format $gformat + } + } + + # pass all the changed values back to parent + debug "$win configChange -size $size -numbytes $numbytes \ + -format $format -ascii $gascii \ + -ascii_char $gascii_char -bytes_per_row $gbpr \ + -color $color" + eval $win configure -size $size -numbytes $numbytes \ + -format $format -ascii $gascii \ + -ascii_char $gascii_char -bytes_per_row $gbpr \ + -color $color + + $win reconfig + + gdbtk_idle + idle +} + +# ------------------------------------------------------------------ +# METHOD: enable_format - turn on the format radio buttons +# ------------------------------------------------------------------ +body MemPref::enable_format {} { + if {!$format_disabled} { + return + } + + foreach widget {rb-binary rb-octal rb-hex rb-signed_dec rb-unsign_dec} { + $Widgets($widget) configure -state normal + } + set format_disabled 0 +} + + +# ------------------------------------------------------------------ +# METHOD: disable_format - turn off the format radio buttons +# ------------------------------------------------------------------ +body MemPref::disable_format {} { + if {$format_disabled} { + return + } + + foreach widget {rb-binary rb-octal rb-hex rb-signed_dec rb-unsign_dec} { + $Widgets($widget) configure -state disabled + } + set format_disabled 1 +} + +# ------------------------------------------------------------------ +# METHOD: pick - pick colors +# ------------------------------------------------------------------ +body MemPref::pick {lab} { + set new_color [tk_chooseColor -initialcolor $color -title "Choose color"] + if {$new_color != $color && $new_color != ""} { + set color $new_color + $lab configure -bg $color + } +} + + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body MemPref::reconfig {} { + # for now, just delete and recreate + destroy $itk_interior.f + build_win +} + diff --git a/gdb/gdbtk/library/mempref.ith b/gdb/gdbtk/library/mempref.ith new file mode 100644 index 00000000000..77c62a3670a --- /dev/null +++ b/gdb/gdbtk/library/mempref.ith @@ -0,0 +1,69 @@ +# Memory display preferences window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class MemPref { + inherit ModalDialog ManagedWin + + public { + variable win + variable size + variable format + variable numbytes + variable bpr + variable ascii + variable ascii_char + variable color + + method constructor {args} + method destructor {} + method busy {} + method idle {} + method cancel {} + method set_bytes_per_row {w value} + method check_numbytes {var index mode} + method toggle_size_control {} + method apply {} + method enable_format {} + method disable_format {} + method pick {lab} + method reconfig {} + } + + private { + # The next seven variables are all used in the radio-buttons + # and checkbuttons of the display. + variable gsize + variable gformat + variable gnumbytes + variable gbpr + variable gascii + variable gascii_char + variable gvar + + variable Widgets + variable WidgetState + variable format_disabled 0 + variable old_numbytes + variable normal_background + method build_win {} + method ok {} + } + + protected { + common float_size "" + common double_size "" + common default_numbytes 128 + } + +} diff --git a/gdb/gdbtk/library/memwin.itb b/gdb/gdbtk/library/memwin.itb new file mode 100644 index 00000000000..eed59a4b3a7 --- /dev/null +++ b/gdb/gdbtk/library/memwin.itb @@ -0,0 +1,739 @@ +# ------------------------------------------------------------------ +# METHOD: constructor - build the dialog +# ------------------------------------------------------------------ +body MemWin::constructor {args} { + global _mem + debug $args + eval itk_initialize $args + + set top [winfo toplevel $itk_interior] + gdbtk_busy + + set _mem($this,enabled) 1 + set bg white + + if {![info exists type(1)]} { + set type(1) char + set type(2) short + set type(4) int + set type(8) "long long" + } + + if {[pref getd gdb/mem/menu] != ""} { + set mbar 0 + } + + init_addr_exp + build_win + gdbtk_idle + + add_hook gdb_update_hook "$this update" + add_hook gdb_busy_hook [list $this busy] + add_hook gdb_idle_hook [list $this idle] +} + +# ------------------------------------------------------------------ +# METHOD: destructor - destroy the dialog +# ------------------------------------------------------------------ +body MemWin::destructor {} { + if {[winfo exists $prefs_win]} { + $prefs_win cancel + } + remove_hook gdb_update_hook "$this update" + remove_hook gdb_busy_hook [list $this busy] + remove_hook gdb_idle_hook [list $this idle] +} + + +# ------------------------------------------------------------------ +# METHOD: build_win - build the main memory window +# ------------------------------------------------------------------ +body MemWin::build_win {} { + global tcl_platform gdb_ImageDir _mem ${this}_memval + + set maxlen 0 + set maxalen 0 + set saved_value "" + + if { $mbar } { + menu $itk_interior.m -tearoff 0 + $top configure -menu $itk_interior.m + $itk_interior.m add cascade -menu $itk_interior.m.addr -label "Addresses" -underline 0 + set m [menu $itk_interior.m.addr] + $m add check -label " Auto Update" -variable _mem($this,enabled) \ + -underline 1 -command "after idle $this toggle_enabled" + $m add command -label " Update Now" -underline 1 \ + -command "$this update_address" -accelerator {Ctrl+U} + $m add separator + $m add command -label " Preferences..." -underline 1 \ + -command "$this create_prefs" + } + + # Numcols = number of columns of data + # numcols = number of columns in table (data plus headings plus ASCII) + # if numbytes are 0, then use window size to determine how many to read + if {$numbytes == 0} { + set Numrows 8 + } else { + set Numrows [expr {$numbytes / $bytes_per_row}] + } + set numrows [expr {$Numrows + 1}] + + set Numcols [expr {$bytes_per_row / $size}] + if {$ascii} { + set numcols [expr {$Numcols + 2}] + } else { + set numcols [expr {$Numcols + 1}] + } + + table $itk_interior.t -titlerows 1 -titlecols 1 -variable ${this}_memval \ + -roworigin -1 -colorigin -1 -bg $bg \ + -browsecmd "$this changed_cell %s %S" -font src-font\ + -colstretch unset -rowstretch unset -selectmode single \ + -xscrollcommand "$itk_interior.sx set" -resizeborders none \ + -cols $numcols -rows $numrows -autoclear 1 + + if {$numbytes} { + $itk_interior.t configure -yscrollcommand "$itk_interior.sy set" + scrollbar $itk_interior.sy -command [list $itk_interior.t yview] + } else { + $itk_interior.t configure -rowstretchmode none + } + scrollbar $itk_interior.sx -command [list $itk_interior.t xview] -orient horizontal + $itk_interior.t tag config sel -bg [$itk_interior.t cget -bg] -relief sunken + $itk_interior.t tag config active -bg lightgray -relief sunken -wrap 0 + + # rebind all events that use tkTableMoveCell to our local version + # because we don't want to move into the ASCII column if it exists + bind $itk_interior.t <Up> "$this memMoveCell %W -1 0; break" + bind $itk_interior.t <Down> "$this memMoveCell %W 1 0; break" + bind $itk_interior.t <Left> "$this memMoveCell %W 0 -1; break" + bind $itk_interior.t <Right> "$this memMoveCell %W 0 1; break" + bind $itk_interior.t <Return> "$this memMoveCell %W 0 1; break" + bind $itk_interior.t <KP_Enter> "$this memMoveCell %W 0 1; break" + + # bind button 3 to popup + bind $itk_interior.t <3> "$this do_popup %X %Y" + + # bind Paste and button2 to the paste function + # this is necessary because we want to not just paste the + # data into the cell, but we also have to write it + # out to real memory + bind $itk_interior.t <ButtonRelease-2> [format {after idle %s paste %s %s} $this %x %y] + bind $itk_interior.t <<Paste>> [format {after idle %s paste %s %s} $this %x %y] + + menu $itk_interior.t.menu -tearoff 0 + bind_plain_key $top Control-u "$this update_address" + + # bind resize events + bind $itk_interior <Configure> "$this newsize %h" + + frame $itk_interior.f + iwidgets::spinint $itk_interior.f.cntl -labeltext " Address " -width 20 \ + -command "after idle $this update_address_cb" \ + -increment "after idle $this incr_addr -1" \ + -decrement "after idle $this incr_addr 1" \ + -validate {} \ + -textbackground white + + $itk_interior.f.cntl delete 0 end + $itk_interior.f.cntl insert end $addr_exp + + balloon register [$itk_interior.f.cntl childsite].uparrow \ + "Scroll Up (Decrement Address)" + balloon register [$itk_interior.f.cntl childsite].downarrow \ + "Scroll Down (Increment Address)" + + if {!$mbar} { + button $itk_interior.f.upd -command "$this update_address" \ + -image [image create photo -file [::file join $gdb_ImageDir check.gif]] + balloon register $itk_interior.f.upd "Update Now" + checkbutton $itk_interior.cb -variable _mem($this,enabled) -command "$this toggle_enabled" + balloon register $itk_interior.cb "Toggles Automatic Display Updates" + grid $itk_interior.f.upd $itk_interior.f.cntl -sticky ew -padx 5 + } else { + grid $itk_interior.f.cntl x -sticky w + grid columnconfigure $itk_interior.f 1 -weight 1 + } + + # draw top border + set col 0 + for {set i 0} {$i < $bytes_per_row} { incr i $size} { + set ${this}_memval(-1,$col) [format " %X" $i] + incr col + } + + if {$ascii} { + set ${this}_memval(-1,$col) ASCII + } + + # fill initial display + if {$nb} { + update_address + } + + if {!$mbar} { + grid $itk_interior.f x -row 0 -column 0 -sticky nws + grid $itk_interior.cb -row 0 -column 1 -sticky news + } else { + grid $itk_interior.f -row 0 -column 0 -sticky news + } + grid $itk_interior.t -row 1 -column 0 -sticky news + if {$numbytes} { grid $itk_interior.sy -row 1 -column 1 -sticky ns } + grid $itk_interior.sx -sticky ew + grid columnconfig $itk_interior 0 -weight 1 + grid rowconfig $itk_interior 1 -weight 1 + focus $itk_interior.f.cntl + + window_name "Memory" +} + +# ------------------------------------------------------------------ +# METHOD: paste - paste callback. Update cell contents after paste +# ------------------------------------------------------------------ +body MemWin::paste {x y} { + edit [$itk_interior.t index @$x,$y] +} + +# ------------------------------------------------------------------ +# METHOD: validate - because the control widget wants this +# ------------------------------------------------------------------ +body MemWin::validate {val} { + return $val +} + +# ------------------------------------------------------------------ +# METHOD: create_prefs - create memory preferences dialog +# ------------------------------------------------------------------ +body MemWin::create_prefs {} { + if {$Running} { return } + + # make sure row height is set + if {$rheight == ""} { + set rheight [lindex [$itk_interior.t bbox 0,0] 3] + } + + set prefs_win [ManagedWin::open MemPref -force -over $this\ + -transient -win $this \ + -size $size -format $format -numbytes $numbytes \ + -bpr $bytes_per_row -ascii $ascii \ + -ascii_char $ascii_char -color $color] +} + +# ------------------------------------------------------------------ +# METHOD: changed_cell - called when moving from one cell to another +# ------------------------------------------------------------------ +body MemWin::changed_cell {from to} { + #debug "moved from $from to $to" + #debug "value = [$itk_interior.t get $from]" + if {$saved_value != ""} { + if {$saved_value != [$itk_interior.t get $from]} { + edit $from + } + } + set saved_value [$itk_interior.t get $to] +} + +# ------------------------------------------------------------------ +# METHOD: edit - edit a cell +# ------------------------------------------------------------------ +body MemWin::edit { cell } { + global _mem ${this}_memval + + #debug "edit $cell" + + if {$Running || $cell == ""} { return } + set rc [split $cell ,] + set row [lindex $rc 0] + set col [lindex $rc 1] + set val [$itk_interior.t get $cell] + + if {$col == $Numcols} { + # editing the ASCII field + set addr [expr {$current_addr + $bytes_per_row * $row}] + set start_addr $addr + + # calculate number of rows to modify + set len [string length $val] + set rows 0 + while {$len > 0} { + incr rows + set len [expr {$len - $bytes_per_row}] + } + set nb [expr {$rows * $bytes_per_row}] + + # now process each char, one at a time + foreach c [split $val ""] { + if {$c != $ascii_char} { + if {$c == "'"} {set c "\\'"} + catch {gdb_cmd "set *(char *)($addr) = '$c'"} + } + incr addr + } + set addr $start_addr + set nextval 0 + # now read back the data and update the widget + catch {gdb_get_mem $addr $format $size $nb $bytes_per_row $ascii_char} vals + for {set n 0} {$n < $nb} {incr n $bytes_per_row} { + set ${this}_memval($row,-1) [format "0x%x" $addr] + for { set col 0 } { $col < [expr {$bytes_per_row / $size}] } { incr col } { + set ${this}_memval($row,$col) [lindex $vals $nextval] + incr nextval + } + set ${this}_memval($row,$col) [lindex $vals $nextval] + incr nextval + incr addr $bytes_per_row + incr row + } + return + } + + # calculate address based on row and column + set addr [expr {$current_addr + $bytes_per_row * $row + $size * $col}] + #debug " edit $row,$col [format "%x" $addr] = $val" + #set memory + catch {gdb_cmd "set *($type($size) *)($addr) = $val"} res + # read it back + # FIXME - HACK ALERT - This call causes trouble with remotes on Windows. + # This routine is in fact called from within an idle handler triggered by + # memMoveCell. Something evil happens in that handler that causes gdb to + # start writing this changed value into all the visible cells... + # I have not figured out the cause of this, so for now I commented this + # line out. It will only matter if the write did not succeed, and this was + # not a very good way to tell the user about that anyway... + # + # catch {gdb_get_mem $addr $format $size $size $size ""} val + # delete whitespace in response + set val [string trimright $val] + set val [string trimleft $val] + set ${this}_memval($row,$col) $val +} + + +# ------------------------------------------------------------------ +# METHOD: toggle_enabled - called when enable is toggled +# ------------------------------------------------------------------ +body MemWin::toggle_enabled {} { + global _mem + + if {$Running} { return } + if {$_mem($this,enabled)} { + update_address + set bg white + set state normal + } else { + set bg gray + set state disabled + } + $itk_interior.t config -background $bg -state $state +} + +# ------------------------------------------------------------------ +# METHOD: update - update widget after every PC change +# ------------------------------------------------------------------ +body MemWin::update {} { + global _mem + if {$_mem($this,enabled)} { + update_address + } +} + +# ------------------------------------------------------------------ +# METHOD: idle - memory window is idle, so enable menus +# ------------------------------------------------------------------ +body MemWin::idle {} { + # Fencepost + set Running 0 + + # Cursor + cursor {} + + # Enable menus + if {$mbar} { + for {set i 0} {$i <= [$itk_interior.m.addr index last]} {incr i} { + if {[$itk_interior.m.addr type $i] != "separator"} { + $itk_interior.m.addr entryconfigure $i -state normal + } + } + } + + # Enable control + $itk_interior.f.cntl configure -state normal +} + + +# ------------------------------------------------------------------ +# METHOD: busy - disable menus 'cause we're busy updating things +# ------------------------------------------------------------------ +body MemWin::busy {} { + # Fencepost + set Running 1 + + # cursor + cursor watch + + # Disable menus + if {$mbar} { + for {set i 0} {$i <= [$itk_interior.m.addr index last]} {incr i} { + if {[$itk_interior.m.addr type $i] != "separator"} { + $itk_interior.m.addr entryconfigure $i -state disabled + } + } + } + + # Disable control + $itk_interior.f.cntl configure -state disabled +} + +# ------------------------------------------------------------------ +# METHOD: newsize - calculate how many rows to display when the +# window is resized. +# ------------------------------------------------------------------ +body MemWin::newsize {height} { + if {$dont_size || $Running} { + return + } + + # only add rows if numbytes is zero + if {$numbytes == 0} { + ::update idletasks + + # make sure row height is set + if {$rheight == ""} { + set rheight [lindex [$itk_interior.t bbox 0,0] 3] + } + + set theight [winfo height $itk_interior.t] + set Numrows [expr {$theight / $rheight}] + $itk_interior.t configure -rows $Numrows + update_addr + } +} + +# ------------------------------------------------------------------ +# METHOD: update_address_cb - address entry widget callback +# ------------------------------------------------------------------ +body MemWin::update_address_cb {} { + set new_entry 1 + update_address [$itk_interior.f.cntl get] +} + +# ------------------------------------------------------------------ +# METHOD: update_address - update address and data displayed +# ------------------------------------------------------------------ +body MemWin::update_address { {ae ""} } { + if {$ae == ""} { + set addr_exp [string trimleft [$itk_interior.f.cntl get]] + } else { + set addr_exp $ae + } + + set saved_addr $current_addr + if {[string match {[a-zA-Z_&0-9\*]*} $addr_exp]} { + # Looks like an expression + set retVal [catch {gdb_eval "$addr_exp"} current_addr] + if {$retVal || [string match "No symbol*" $current_addr] || \ + [string match "Invalid *" $current_addr]} { + BadExpr $current_addr + return + } + if {[string match {\{*} $current_addr]} { + set current_addr [lindex $current_addr 1] + if {$current_addr == ""} { + return + } + } + } elseif {[string match {\$*} $addr_exp]} { + # Looks like a local variable + catch {gdb_eval "$addr_exp"} current_addr + if {$current_addr == "No registers.\n"} { + # we asked for a register value and debugging hasn't started yet + return + } + if {$current_addr == "void"} { + BadExpr "No Local Variable Named \"$addr_ex\"" + return + } + } else { + # something really strange, like "0.1" or "" + BadExpr "Can't Evaluate \"$addr_expr\"" + return + } + + # Check for spaces + set index [string first \ $current_addr] + if {$index != -1} { + incr index -1 + set current_addr [string range $current_addr 0 $index] + } + + # set table background + $itk_interior.t config -bg white -state normal + catch {update_addr} +} + +# ------------------------------------------------------------------ +# METHOD: BadExpr - handle a bad expression +# ------------------------------------------------------------------ +body MemWin::BadExpr {errTxt} { + if {$new_entry} { + tk_messageBox -type ok -icon error -message $errTxt + set new_entry 0 + } + # set table background to gray + $itk_interior.t config -bg gray -state disabled + set current_addr $saved_addr + set saved_addr "" +} + +# ------------------------------------------------------------------ +# METHOD: incr_addr - callback from control widget to increment +# the current address. +# ------------------------------------------------------------------ +body MemWin::incr_addr {num} { + + if {$current_addr == ""} { + return + } + set old_addr $current_addr + + # You have to be careful with address calculations here, since the memory + # space of the target may be bigger than a long, which will cause Tcl to + # overflow. Let gdb do the calculations instead. + + set current_addr [gdb_cmd "printf \"%u\", $current_addr + $num * $bytes_per_row"] + + # A memory address less than zero is probably not a good thing... + # + + if {($num < 0 && [gdb_eval "$current_addr > $old_addr"]) \ + ||($num > 0 && [gdb_eval "$current_addr < $old_addr"]) } { + bell + set current_addr $old_addr + return + } + $itk_interior.t config -background white -state normal + update_addr + $itk_interior.f.cntl clear + $itk_interior.f.cntl insert 0 [format "0x%x" $current_addr] +} + + +# ------------------------------------------------------------------ +# METHOD: update_addr - read in data starting at $current_addr +# This is just a helper function for update_address. +# ------------------------------------------------------------------ +body MemWin::update_addr {} { + global _mem ${this}_memval + + gdbtk_busy + set addr $current_addr + + set row 0 + + if {$numbytes == 0} { + set nb [expr {$Numrows * $bytes_per_row}] + } else { + set nb $numbytes + } + set nextval 0 + set num [expr {$bytes_per_row / $size}] + if {$ascii} { + set asc $ascii_char + } else { + set asc "" + } + + set retVal [catch {gdb_get_mem $addr $format \ + $size $nb $bytes_per_row $asc} vals] + + if {$retVal || [llength $vals] == 0} { + # FIXME gdb_get_mem does not always return an error when addr is invalid. + BadExpr "Couldn't get memory at address: \"$addr\"" + gdbtk_idle + debug "gdb_get_mem returned return code: $retVal and value: \"$vals\"" + return + } + + set mlen 0 + for {set n 0} {$n < $nb} {incr n $bytes_per_row} { + set x [format "0x%x" $addr] + if {[string length $x] > $mlen} { + set mlen [string length $x] + } + set ${this}_memval($row,-1) $x + for { set col 0 } { $col < $num } { incr col } { + set x [lindex $vals $nextval] + if {[string length $x] > $maxlen} {set maxlen [string length $x]} + set ${this}_memval($row,$col) $x + incr nextval + } + if {$ascii} { + set x [lindex $vals $nextval] + if {[string length $x] > $maxalen} {set maxalen [string length $x]} + set ${this}_memval($row,$col) $x + incr nextval + } + incr addr $bytes_per_row + incr row + } + # set default column width to the max in the data columns + $itk_interior.t configure -colwidth [expr {$maxlen + 1}] + # set border column width + $itk_interior.t width -1 [expr {$mlen + 1}] + if {$ascii} { + # set ascii column width + $itk_interior.t width $Numcols [expr {$maxalen + 1}] + } + + gdbtk_idle +} + +# ------------------------------------------------------------------ +# METHOD: hidemb - hide the menubar. NOT CURRENTLY USED +# ------------------------------------------------------------------ +body MemWin::hidemb {} { + set mbar 0 + reconfig +} + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body MemWin::reconfig {} { + debug + set addr_exp [string trimright [string trimleft $addr_exp]] + set wh [winfo height $top] + + if [winfo exists $itk_interior.m] { destroy $itk_interior.m } + if [winfo exists $itk_interior.cb] { destroy $itk_interior.cb } + if [winfo exists $itk_interior.f.upd] { destroy $itk_interior.f.upd } + if [winfo exists $itk_interior.sy] { destroy $itk_interior.sy } + destroy $itk_interior.f.cntl $itk_interior.f $itk_interior.t $itk_interior.sx + + set dont_size 1 + + # If the fonts change, then you will need to recompute the + # row height. Ditto for switch from fixed number of rows to + # depends on size. + + set rheight "" + + build_win + set dont_size 0 + ::update + + if {$numbytes == 0} { + newsize $wh + } +} + +# ------------------------------------------------------------------ +# METHOD: do_popup - Display popup menu +# ------------------------------------------------------------------ +body MemWin::do_popup {X Y} { + if {$Running} { return } + $itk_interior.t.menu delete 0 end + $itk_interior.t.menu add check -label "Auto Update" -variable _mem($this,enabled) \ + -underline 0 -command "$this toggle_enabled" + $itk_interior.t.menu add command -label "Update Now" -underline 0 \ + -command "$this update_address" + $itk_interior.t.menu add command -label "Go To [$itk_interior.t curvalue]" -underline 0 \ + -command "$this goto [$itk_interior.t curvalue]" + $itk_interior.t.menu add command -label "Open New Window at [$itk_interior.t curvalue]" -underline 0 \ + -command [list ManagedWin::open -force MemWin -addr_exp [$itk_interior.t curvalue]] + $itk_interior.t.menu add separator + $itk_interior.t.menu add command -label "Preferences..." -underline 0 \ + -command "$this create_prefs" + tk_popup $itk_interior.t.menu $X $Y +} + +# ------------------------------------------------------------------ +# METHOD: goto - change the address of the current memory window +# ------------------------------------------------------------------ +body MemWin::goto { addr } { + set current_addr $addr + $itk_interior.f.cntl delete 0 end + $itk_interior.f.cntl insert end $addr +} + +# ------------------------------------------------------------------ +# METHOD: init_addr_exp - initialize address expression +# On startup, if the public variable "addr_exp" was not set, +# then set it to the start of ".data" if found, otherwise "$pc" +# ------------------------------------------------------------------ +body MemWin::init_addr_exp {} { + if {$addr_exp == ""} { + set err [catch {gdb_cmd "info file"} result] + if {!$err} { + foreach line [split [string trim $result] \n] { + if {[scan $line {%x - %x is %s} start stop section] == 3} { + if {$section == ".data"} { + set addr_exp [format "%#08x" $start] + break + } + } + } + } + if {$addr_exp == ""} { + set addr_exp \$pc + } + } +} + +# ------------------------------------------------------------------ +# METHOD: cursor - set the cursor +# ------------------------------------------------------------------ +body MemWin::cursor {glyph} { + # Set cursor for all labels + # for {set i 0} {$i < $bytes_per_row} {incr i $size} { + # $itk_interior.t.h.$i configure -cursor $glyph + # } + $top configure -cursor $glyph +} + +# memMoveCell -- +# +# Moves the location cursor (active element) by the specified number +# of cells and changes the selection if we're in browse or extended +# selection mode. +# +# Don't allow movement into the ASCII column. +# +# Arguments: +# w - The table widget. +# x - +1 to move down one cell, -1 to move up one cell. +# y - +1 to move right one cell, -1 to move left one cell. + +body MemWin::memMoveCell {w x y} { + if {[catch {$w index active row} r]} return + set c [$w index active col] + if {$ascii && ($c == $Numcols)} { + # we're in the ASCII column so behave differently + if {$y == 1} {set x 1} + if {$y == -1} {set x -1} + incr r $x + } else { + incr r $x + incr c $y + if { $c < 0 } { + if {$r == 0} { + set c 0 + } else { + set c [expr {$Numcols - 1}] + incr r -1 + } + } elseif { $c >= $Numcols } { + if {$r >= [expr {$Numrows - 1}]} { + set c [expr {$Numcols - 1}] + } else { + set c 0 + incr r + } + } + } + if { $r < 0 } { set r 0 } + $w activate $r,$c + $w see active +} + diff --git a/gdb/gdbtk/library/memwin.ith b/gdb/gdbtk/library/memwin.ith new file mode 100644 index 00000000000..fd2bc0d93fe --- /dev/null +++ b/gdb/gdbtk/library/memwin.ith @@ -0,0 +1,78 @@ +# Memory display window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class MemWin { + inherit EmbeddedWin GDBWin + + private { + variable saved_addr "" + variable current_addr "" + variable dont_size 0 + variable mbar 1 + variable bg + variable top + variable nb 128 + variable prefs_win "" + variable Running 0 + variable Numrows 0 + variable Numcols 0 + variable saved_value + variable maxlen + variable maxalen + variable rheight "" + variable new_entry 0 + + method build_win {} + method init_addr_exp {} + method cursor {glyph} + } + + public { + variable addr_exp "" + variable size 4 + variable format x + variable bytes_per_row 16 + variable numbytes 0 + variable ascii 1 + variable ascii_char "." + variable color green + } + + protected common type + + public { + method constructor {args} + method destructor {} + method paste {x y} + method validate {val} + method create_prefs {} + method changed_cell {from to} + method edit {cell} + method toggle_enabled {} + method update {} + method idle {} + method busy {} + method newsize {height} + method update_address_cb {} + method update_address { {ae ""} } + method BadExpr {errTxt} + method incr_addr {num} + method update_addr + method hidemb {} + method reconfig {} + method do_popup {x y} + method goto {addr} + method memMoveCell {w x y} + } +} diff --git a/gdb/gdbtk/library/modal.tcl b/gdb/gdbtk/library/modal.tcl new file mode 100644 index 00000000000..e2c09eb0fd7 --- /dev/null +++ b/gdb/gdbtk/library/modal.tcl @@ -0,0 +1,105 @@ +# Modal dialog class for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements the post and unpost behavior of a Modal Dialog. +# +# For now the point behind this is to control calling +# ide_grab_support. If you call disable all the windows of an +# application but one, destroy that window, THEN re-enable the +# windows, Windows brings the last enabled window in the last +# active application to the foreground (Doh!). +# +# ---------------------------------------------------------------------- + +class ModalDialog { + # This is the variable we vwait on when the dialog is posted. + # It is set to 1 in the unpost method, and to -1 in the destructor. + + private variable unpost_notification 0 + + destructor { + debug " UNPOST $this" + set unpost_notification -1 + } + + # ------------------------------------------------------------------ + # METHOD: unpost - unposts the dialog box... + # ------------------------------------------------------------------ + public method unpost {} { + after idle [list set [scope unpost_notification] 1] + } + + # ------------------------------------------------------------------ + # METHOD: cancel - This just unposts the dialog box... + # If you want to programatically cancel a dialog + # selection, for instance if the app is going away + # use this rather than unpost. That way a sub-class + # that actually has to do some work can override it. + # ------------------------------------------------------------------ + public method cancel {} { + ModalDialog::unpost + } + + + # ------------------------------------------------------------------ + # METHOD: post - posts the dialog box... + # ------------------------------------------------------------------ + public method post {{on_top 0}} { + + debug "POST $this" + set top [winfo toplevel [namespace tail $this]] + wm protocol $top WM_DELETE_WINDOW [code $this cancel] + + if {$on_top} { + after 500 keep_raised $top + } + + ide_grab_support disable_except $top + focus $top + grab set $top + + if {$expire > 0} { + set afterID [after $expire [code $this cancel]] + } + + vwait [scope unpost_notification] + + if {$afterID != ""} { + after cancel $afterID + set afterID "" + } + + grab release $top + + # Enable all the windows in the application BEFORE + # you destroy this one, or Windows will bring another + # app to the foreground. + + ide_grab_support enable_all + + # We can get here either by someone calling unpost (if an OK button + # is clicked or whatever), or by someone destroying the dialog (for + # instance by using the Window Manager.) Only delete the object if + # we are not already in the process of doing this. + + if {$unpost_notification == 1} { + ::delete object $this + } + } + + public variable expire -1 ;# If this is set to a number > 0, the + # dialog will time out after this interval. + private variable afterID ""; # The id for the expiration after event. +} diff --git a/gdb/gdbtk/library/prefs.tcl b/gdb/gdbtk/library/prefs.tcl new file mode 100644 index 00000000000..bc69b131f53 --- /dev/null +++ b/gdb/gdbtk/library/prefs.tcl @@ -0,0 +1,343 @@ +# Local preferences functions for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# On STARTUP: +# 1. Options database (.Xdefaults on Unix or ? on Windows) is read +# 2. GDB prefs file is read ("gdbtk.ini" on Windows; ".gdbtkinit" on Unix) +# 3. GDB init script is read +# +# Normally all preferences will be set in the prefs file, which is +# a generated file. Hand-editing, if necessary, should be done to the +# GDB init script. +# +# when "save options" is selected, the contents of the +# preferences array is written out to the GDB prefs file. +# +# Usage: +# pref_save +# pref_read +# ---------------------------------------------------------------------- +# + +proc pref_read {} { + global prefs_init_filename env gdb_ImageDir GDBTK_LIBRARY GDBStartup + global tcl_platform + + if {[info exists env(HOME)]} { + if {$tcl_platform(platform) == "windows"} { + set home [ide_cygwin_path to_win32 $env(HOME)] + } else { + set home $env(HOME) + } + } else { + set home "" + } + + if {$tcl_platform(platform) == "windows"} { + set prefs_init_filename "gdbtk.ini" + } else { + set prefs_init_filename ".gdbtkinit" + } + + if {!$GDBStartup(inhibit_prefs)} { + set file_opened 0 + if {[file exists $prefs_init_filename]} { + if {[catch {open $prefs_init_filename r} fd]} { + debug "$fd" + return + } + set file_opened 1 + } elseif {$home != ""} { + set name [file join $home $prefs_init_filename] + if {[file exists $name]} { + if {[catch {open $name r} fd]} { + debug "$fd" + return + } + set prefs_init_filename $name + set file_opened 1 + } + } + + if {$file_opened == "1"} { + set section gdb + while {[gets $fd line] >= 0} { + switch -regexp -- $line { + {^[ \t\n]*#.*} { + ;# comment; ignore it + } + + {^[ \t\n]*$} { + ;# empty line; ignore it + } + + {\[.*\]} { + regexp {\[(.*)\]} $line match section + } + + {[ \t\n]*option.*} { + set line [string trimleft $line] + eval $line + } + + default { + regexp "\[ \t\n\]*\(.+\)=\(.+\)" $line a name val + # Must unescape equal signs in val + set val [unescape_value $val] + if {$section == "gdb"} { + pref setd gdb/$name $val + } elseif {$section == "global" && [regexp "^font/" $name]} { + set name [split $name /] + set f global/ + append f [join [lrange $name 1 end] /] + if {[lsearch [font names] $f] == -1} { + # new font + eval define_font $f $val + } else { + # existing font + pref set global/font/[join [lrange $name 1 end] /] $val + } + } elseif {$section == "global"} { + pref setd $section/$name $val + } else { + pref setd gdb/$section/$name $val + } + } + } + } + close $fd + } elseif {$home != ""} { + set prefs_init_filename [file join $home $prefs_init_filename] + } + + # now set global options + set gdb_ImageDir [file join $GDBTK_LIBRARY [pref get gdb/ImageDir]] + } +} + +# ------------------------------------------------------------------ +# PROC: pref_save - save preferences to a file and delete window +# ------------------------------------------------------------------ +proc pref_save {{win {}}} { + global prefs_init_filename GDBStartup + + if {!$GDBStartup(inhibit_prefs)} { + debug "pref_save $prefs_init_filename" + + if {[catch {open $prefs_init_filename w} fd]} { + debug "ERROR: $fd" + return + } + + puts $fd "\# GDBtk Init file" + + set plist [pref list] + # write out global options + puts $fd "\[global\]" + foreach var $plist { + set t [split $var /] + if {[lindex $t 0] == "global"} { + set x [join [lrange $t 1 end] /] + set v [escape_value [pref get $var]] + + if {$x != "" && $v != ""} { + puts $fd "\t$x=$v" + } + } + } + + # write out gdb-global options + puts $fd "\[gdb\]" + foreach var $plist { + set t [split $var /] + if {[lindex $t 0] == "gdb" && [lindex $t 2] == ""} { + set x [lindex $t 1] + if {$x != ""} { + set v [escape_value [pref get $var]] + puts $fd "\t$x=$v" + } + } + } + + #now loop through all sections writing out values + lappend secs load console src reg stack locals watch bp search process geometry help browser kod + + foreach section $secs { + puts $fd "\[$section\]" + foreach var $plist { + set t [split $var /] + if {[lindex $t 0] == "gdb" && [lindex $t 1] == $section} { + set x [lindex $t 2] + set v [escape_value [pref get $var]] + if {$x != "" && $v != ""} { + puts $fd "\t$x=$v" + } + } + } + } + close $fd + } + + if {$win != ""} { + $win delete + } +} + +# ------------------------------------------------------- +# PROC: escape_value - escape all equal signs for saving +# prefs to a file +# ------------------------------------------------------- +proc escape_value {val} { + + if {[regsub -all -- = $val {!%} newval]} { + return $newval + } + + return $val +} + +# ------------------------------------------------------- +# PROC: unescape_value - unescape all equal signs for +# reading prefs from a file +# ------------------------------------------------------- +proc unescape_value {val} { + + if {[regsub -all -- {!%} $val = newval]} { + return $newval + } + + return $val +} + +# ------------------------------------------------------------------ +# PROC: pref_set_defaults - set up default values +# ------------------------------------------------------------------ +proc pref_set_defaults {} { + global GDBTK_LIBRARY tcl_platform gdb_ImageDir + + # Gdb global defaults + pref define gdb/ImageDir images2 + set gdb_ImageDir [file join $GDBTK_LIBRARY [pref get gdb/ImageDir]] + pref define gdb/font_cache "" + pref define gdb/mode 0; # 0 no tracing, 1 tracing enabled + pref define gdb/control_target 1; # 0 can't control target (EMC), 1 can + pref define gdb/B1_behavior 1; # 0 means set/clear breakpoints, + # 1 means set/clear tracepoints. + pref define gdb/use_icons 1; # For Unix, use gdbtk_icon.gif as an icon + # some window managers can't deal with it. + + # set download and execution options + pref define gdb/load/verbose 0 + pref define gdb/load/main 1 + pref define gdb/load/exit 1 + pref define gdb/load/check 0 + pref define gdb/load/bp_at_func 0 + pref define gdb/load/bp_func "" + pref define gdb/load/baud 38400 + if {$tcl_platform(platform) == "windows"} { + pref define gdb/load/port com1 + } else { + pref define gdb/load/port "/dev/ttyS0" + } + + # Console defaults + pref define gdb/console/prompt "(gdb) " + pref define gdb/console/deleteLeft 1 + pref define gdb/console/wrap 0 + pref define gdb/console/prompt_fg DarkGreen + pref define gdb/console/error_fg red + pref define gdb/console/font src-font + + # Source window defaults + pref define gdb/src/PC_TAG green + pref define gdb/src/STACK_TAG gold + pref define gdb/src/BROWSE_TAG \#9595e2 + pref define gdb/src/active 1 + pref define gdb/src/handlebg red + pref define gdb/src/bp_fg red + pref define gdb/src/temp_bp_fg orange + pref define gdb/src/disabled_fg black + pref define gdb/src/font src-font + pref define gdb/src/break_fg black + pref define gdb/src/source2_fg navy + pref define gdb/src/variableBalloons 1 + pref define gdb/src/trace_fg magenta + pref define gdb/src/tab_size 8 + pref define gdb/src/linenums 1 + pref define gdb/src/thread_fg pink + + # Define the run button's functions. These are defined here in case + # we do a "run" with an exec target (which never causes target.tcl to + # source)... + pref define gdb/src/run_attach 0 + pref define gdb/src/run_load 0 + pref define gdb/src/run_run 1 + pref define gdb/src/run_cont 0 + + # This is the disassembly flavor. For now this is only supported on x86 + # machines. + + pref define gdb/src/disassembly-flavor "" + + # set up src-font + set val [pref get global/font/fixed] + eval font create src-font $val + + # Trace the global/font/fixed preference + pref add_hook global/font/fixed pref_src-font_trace + + # Variable Window defaults + pref define gdb/variable/font src-font + pref define gdb/variable/highlight_fg blue + pref define gdb/variable/disabled_fg gray + + # Stack Window + pref define gdb/stack/font src-font + + # Register Window + pref define gdb/reg/highlight_fg blue + + # Global Prefs Dialogs + pref define gdb/global_prefs/save_fg red + pref define gdb/global_prefs/message_fg white + pref define gdb/global_prefs/message_bg red + + # Browser Window Search + pref define gdb/search/last_symbol "" + pref define gdb/search/filter_mode "starts with" + + pref define gdb/browser/hide_h 0 + pref define gdb/browser/width 0 + pref define gdb/browser/top_height 0 + pref define gdb/browser/view_height -1 + pref define gdb/browser/view_is_open 0 + + # BP (breakpoint) + pref define gdb/bp/show_threads 0 + + # Help + pref define gdb/help/browser 0 + + # Kernel Objects (kod) + pref define gdb/kod/show_icon 0 + + # Various possible "main" functions. What's for Java? + pref define gdb/main_names [list MAIN___ MAIN__ main] +} + +# This traces the global/fixed font and forces src-font to +# to be the same. +proc pref_src-font_trace {varname val} { + eval font configure src-font $val +} diff --git a/gdb/gdbtk/library/process.itb b/gdb/gdbtk/library/process.itb new file mode 100644 index 00000000000..07638d5ab4f --- /dev/null +++ b/gdb/gdbtk/library/process.itb @@ -0,0 +1,172 @@ +# Process window for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements a process window with a list of threads, tasks, and/or +# processes to debug. +# +# ---------------------------------------------------------------------- + +body ProcessWin::constructor {args} { + set top [winfo toplevel $itk_interior] + + window_name "Processes" + gdbtk_busy + build_win + gdbtk_idle + + # Add hooks for this object + add_hook gdb_update_hook [code $this update] + add_hook gdb_busy_hook [code $this busy] + add_hook gdb_no_inferior_hook [code $this idle] + add_hook gdb_idle_hook [code $this idle] +} + + +# ------------------------------------------------------------------ +# METHOD: build_win - build the main process window +# ------------------------------------------------------------------ +body ProcessWin::build_win {} { + global tixOption tcl_platform + if {$tcl_platform(platform) == "windows"} { + tixScrolledListBox $itk_interior.s -scrollbar both -sizebox 1 + } else { + tixScrolledListBox $itk_interior.s -scrollbar auto + } + set lb [$itk_interior.s subwidget listbox] + $lb configure -selectmode single -bg $tixOption(input1_bg) \ + -selectbackground green \ + -selectforeground black \ + -font src-font \ + -exportselection false + update + balloon register $lb "Click on a line to change context" + + # bind mouse button 1 to change the current context + bind $lb <ButtonPress-1> [code $this change_context %y] + bind $lb <ButtonRelease-1> break + + pack $itk_interior.s -side left -expand yes -fill both +} + + +# ------------------------------------------------------------------ +# METHOD: update - update widget when something changes +# ------------------------------------------------------------------ +body ProcessWin::update {} { + if {!$protect_me} { + + $lb delete 0 end + if {[catch {gdb_cmd "info thread"} threads]} { + # failed. leave window blank + return + } + + #debug "processWin update: \n$threads" + if {[llength $threads] == 0} { + # no processes/threads listed. + return + } + + # insert each line one at a time + set active -1 + set num_threads 0 + foreach line [split $threads \n] { + # Active line starts with "*" + if {[string index $line 0] == "*"} { + # strip off leading "*" + set line " [string trimleft $line "*"]" + set active $num_threads + } + # scan for GDB ID number at start of line + if {[scan $line "%d" id($num_threads)] == 1} { + $lb insert end $line + incr num_threads + } + } + + # highlight the active thread + if {$active >= 0} { + set active_thread $id($active) + $lb selection set $active + $lb see $active + } + } +} + +# ------------------------------------------------------------------ +# METHOD: change_context - change the current context (active thread) +# This method is currently ONLY called from the mouse binding +# ------------------------------------------------------------------ +body ProcessWin::change_context {y} { + if {!$Running && [$lb size] != 0} { + gdbtk_busy + set linenum [$lb nearest $y] + set idnum $id($linenum) + #debug "change_context to line $linenum id=$idnum" + catch {gdb_cmd "thread $idnum"} + # Run idle hooks and cause all widgets to update + set protect_me 1 + gdbtk_update + set protect_me 0 + gdbtk_idle + } +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body ProcessWin::destructor {} { + remove_hook gdb_update_hook [code $this update] + remove_hook gdb_idle_hook [code $this idle] + remove_hook gdb_busy_hook [code $this busy] + remove_hook gdb_no_inferior_hook [code $this no_inferior] +} + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body ProcessWin::reconfig {} { + destroy $itk_interior.s + build_win +} + +# ------------------------------------------------------------------ +# METHOD: busy - gdb_busy_hook +# +# This method should accomplish blocking +# - clicks in the window +# - change mouse pointer +# ------------------------------------------------------------------ +body ProcessWin::busy {} { + set Running 1 + cursor watch +} + +# ------------------------------------------------------------------ +# METHOD: idle - idle hook. Run when the target is not running +# ------------------------------------------------------------------ +body ProcessWin::idle {} { + set Running 0 + cursor {} +} + +# ------------------------------------------------------------------ +# METHOD: cursor - set the window cursor +# This is a convenience method which simply sets the mouse +# pointer to the given glyph. +# ------------------------------------------------------------------ +body ProcessWin::cursor {glyph} { + $top configure -cursor $glyph +} diff --git a/gdb/gdbtk/library/process.ith b/gdb/gdbtk/library/process.ith new file mode 100644 index 00000000000..d9b8fece4ee --- /dev/null +++ b/gdb/gdbtk/library/process.ith @@ -0,0 +1,40 @@ +# Process window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class ProcessWin { + inherit EmbeddedWin GDBWin + + private { + variable top + variable lb + variable id + variable Running 0 + variable protect_me 0 + + + method build_win {} + method change_context {y} + method cursor {glyph} + method change_frame {y} + method update {} + method busy {} + method idle {} + } + + public { + method reconfig {} + method constructor {args} + method destructor {} + } +}
\ No newline at end of file diff --git a/gdb/gdbtk/library/regwin.itb b/gdb/gdbtk/library/regwin.itb new file mode 100644 index 00000000000..2515498c06e --- /dev/null +++ b/gdb/gdbtk/library/regwin.itb @@ -0,0 +1,585 @@ +# Register display window for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new register window +# ------------------------------------------------------------------ +body RegWin::constructor {args} { + global tixOption + debug "RegWin::constructor" + wm withdraw [winfo toplevel $itk_interior] + gdbtk_busy + + set NormalForeground $tixOption(fg) + set HighlightForeground [pref get gdb/reg/highlight_fg] + + if {[pref getd gdb/reg/menu] != ""} { + set mbar 0 + } + + init_reg_display_vars 1 + build_win + eval itk_initialize $args + + gdbtk_idle + add_hook gdb_update_hook "$this update" + add_hook gdb_busy_hook [list $this busy] + add_hook gdb_idle_hook [list $this idle] + if {[get_disassembly_flavor] != ""} { + add_hook gdb_set_hook [code $this handle_set_hook] + } +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body RegWin::destructor {} { + debug "RegWin::destructor" + remove_hook gdb_update_hook "$this update" + remove_hook gdb_busy_hook [list $this busy] + remove_hook gdb_idle_hook [list $this idle] + if {[get_disassembly_flavor] != ""} { + remove_hook gdb_set_hook [code $this handle_set_hook] + } +} + + + +# ------------------------------------------------------------------ +# METHOD: build_win - build the main register window +# ------------------------------------------------------------------ +body RegWin::build_win {} { + global reg_display tixOption tcl_platform + + set dim [dimensions] + set nRows [lindex $dim 0] + set nCols [lindex $dim 1] + if {$tcl_platform(platform) == "windows"} { + tixScrolledWindow $itk_interior.scrolled -scrollbar both -sizebox 1 + } else { + tixScrolledWindow $itk_interior.scrolled -scrollbar auto + } + set ScrolledWin [$itk_interior.scrolled subwidget window] + # Create labels + set row 0 + set col 0 + + set regMaxLen 0 + foreach r [gdb_regnames] { + set l [string length $r] + if {$l > $regMaxLen} { + set regMaxLen $l + } + } + + set vmax 0 + foreach r $reg_display_list { + if {[catch {gdb_fetch_registers $reg_display($r,format) $r} values($r)]} { + set values($r) "" + } else { + set values($r) [string trim $values($r) \ ] + } + set l [string length $values($r)] + if {$l > $vmax} { + set vmax $l + } + } + + foreach r $reg_display_list { + if {$row == $nRows} { + grid columnconfigure $ScrolledWin $col -weight 1 + set row 0 + incr col + } + + frame $ScrolledWin.$r -takefocus 1 + bind $ScrolledWin.$r <Up> "$this reg_select_up" + bind $ScrolledWin.$r <Down> "$this reg_select_down" + bind $ScrolledWin.$r <Tab> "$this reg_select_down" + bind $ScrolledWin.$r <Left> "$this reg_select_left" + bind $ScrolledWin.$r <Right> "$this reg_select_right" + if {![pref get gdb/mode]} { + bind $ScrolledWin.$r <Return> "$this edit $r" + } + + label $ScrolledWin.$r.lbl -text [fixLength $reg_display($r,name) $regMaxLen left] \ + -relief solid -bd 1 -font src-font + label $ScrolledWin.$r.val -anchor e -text [fixLength $values($r) $vmax right] \ + -relief ridge -bd 1 -font src-font -bg $tixOption(input1_bg) + + grid $ScrolledWin.$r.lbl $ScrolledWin.$r.val -sticky nsew + grid columnconfigure $ScrolledWin.$r 1 -weight 1 + grid $ScrolledWin.$r -colum $col -row $row -sticky nsew + # grid rowconfigure $ScrolledWin $row -weight 1 + bind $ScrolledWin.$r.val <1> "$this reg_select $r" + bind $ScrolledWin.$r.lbl <1> "$this reg_select $r" + bind $ScrolledWin.$r.val <3> "$this but3 $r %X %Y" + bind $ScrolledWin.$r.lbl <3> "$this but3 $r %X %Y" + if {![pref get gdb/mode]} { + bind $ScrolledWin.$r.lbl <Double-1> "$this edit $r" + bind $ScrolledWin.$r.val <Double-1> "$this edit $r" + } + incr row + } + grid columnconfigure $ScrolledWin $col -weight 1 + + + if { $mbar } { + menu $itk_interior.m -tearoff 0 + [winfo toplevel $itk_interior] configure -menu $itk_interior.m + $itk_interior.m add cascade -menu $itk_interior.m.reg -label "Register" -underline 0 + set m [menu $itk_interior.m.reg] + if {![pref get gdb/mode]} { + $m add command -label "Edit" -underline 0 -state disabled + } + $m add cascade -menu $itk_interior.m.reg.format -label "Format" -underline 0 + set f [menu $itk_interior.m.reg.format] + $f add radio -label "Hex" -value x -underline 0 -state disabled \ + -command "$this update" + $f add radio -label "Decimal" -value d -underline 0 -state disabled \ + -command "$this update" + $f add radio -label "Natural" -value {} -underline 0 -state disabled \ + -command "$this update" + $f add radio -label "Binary" -value t -underline 0 -state disabled \ + -command "$this update" + $f add radio -label "Octal" -value o -underline 0 -state disabled \ + -command "$this update" + $f add radio -label "Raw" -value r -underline 0 -state disabled \ + -command "$this update" + $m add command -label "Remove from Display" -underline 0 -state disabled + $m add separator + $m add command -label "Display All Registers" -underline 0 -state disabled \ + -command "$this display_all" + } + + set Menu [menu $ScrolledWin.pop -tearoff 0] + set disabled_fg [$Menu cget -fg] + $Menu configure -disabledforeground $disabled_fg + + # Clear gdb's changed list + catch {gdb_changed_register_list} + + pack $itk_interior.scrolled -anchor nw -fill both -expand yes + + window_name "Registers" "Regs" +} + +# ------------------------------------------------------------------------------ +# NAME: init_reg_display_vars +# DESC: Initialize the list of registers displayed. +# args - not used +# RETURNS: +# NOTES: +# ------------------------------------------------------------------------------ +body RegWin::init_reg_display_vars {args} { + global reg_display max_regs + set reg_display_list {} + set regnames [gdb_regnames] + set i 1 + set rn 0 + foreach r $regnames { + set reg_display($rn,name) $r + set format [pref getd gdb/reg/$r-format] + if {$format == ""} { set format x } + set reg_display($rn,format) $format + if {$args != "" && [pref getd gdb/reg/$r] == "no"} { + set reg_display($rn,line) 0 + } else { + set reg_display($rn,line) $i + lappend reg_display_list $rn + incr i + } + incr rn + } + set num_regs [expr {$i - 1}] + set max_regs $rn + set reg_names_dirty 0 +} + +body RegWin::handle_set_hook {var value} { + switch $var { + disassembly-flavor { + disassembly_changed + } + } +} + +body RegWin::disassembly_changed {} { + set reg_names_dirty 1 +} +# ------------------------------------------------------------------------------ +# NAME: save_reg_display_vars +# DESC: save the list of displayed registers to the preferences file. +# ------------------------------------------------------------------------------ +body RegWin::save_reg_display_vars {} { + global reg_display max_regs + set rn 0 + while {$rn < $max_regs} { + set name $reg_display($rn,name) + if {$reg_display($rn,line) == 0} { + pref setd gdb/reg/$name no + } else { + pref setd gdb/reg/$name {} + } + if {$reg_display($rn,format) != "x"} { + pref setd gdb/reg/$name-format $reg_display($rn,format) + } else { + pref setd gdb/reg/$name-format {} + } + incr rn + } + pref_save "" +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: reg_select_up +# ------------------------------------------------------------------ +body RegWin::reg_select_up { } { + if { $selected == -1 || $Running} { + return + } + set current_index [lsearch -exact $reg_display_list $selected] + set new_reg [lindex $reg_display_list [expr {$current_index - 1}]] + if { $new_reg != {} } { + $this reg_select $new_reg + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: reg_select_down +# ------------------------------------------------------------------ +body RegWin::reg_select_down { } { + if { $selected == -1 || $Running} { + return + } + set current_index [lsearch -exact $reg_display_list $selected] + set new_reg [lindex $reg_display_list [expr {$current_index + 1}]] + if { $new_reg != {} } { + $this reg_select $new_reg + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: reg_select_right +# ------------------------------------------------------------------ +body RegWin::reg_select_right { } { + if { $selected == -1 || $Running} { + return + } + set current_index [lsearch -exact $reg_display_list $selected] + set new_reg [lindex $reg_display_list [expr {$current_index + $nRows}]] + if { $new_reg != {} } { + $this reg_select $new_reg + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: reg_select_left +# ------------------------------------------------------------------ +body RegWin::reg_select_left { } { + if { $selected == -1 || $Running} { + return + } + set current_index [lsearch -exact $reg_display_list $selected] + set new_reg [lindex $reg_display_list [expr {$current_index - $nRows}]] + if { $new_reg != {} } { + $this reg_select $new_reg + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: reg_select - select a register +# ------------------------------------------------------------------ +body RegWin::reg_select { r } { + global tixOption + + if {$Running} { return } + if {$selected != -1} { + catch {$ScrolledWin.$selected.lbl configure -fg $tixOption(fg) -bg $tixOption(bg)} + catch {$ScrolledWin.$selected.val configure -fg $tixOption(fg) \ + -bg $tixOption(input1_bg)} + } + + # if we click on the same line, unselect it and return + if {$selected == $r} { + set selected -1 + $itk_interior.m.reg entryconfigure 0 -state disabled + $itk_interior.m.reg entryconfigure 2 -state disabled + for {set i 0} {$i < 6} {incr i} { + $itk_interior.m.reg.format entryconfigure $i -state disabled + } + return + } + + if {$Editing != -1} { + unedit + } + + $ScrolledWin.$r.lbl configure -fg $tixOption(select_fg) -bg $tixOption(select_bg) + $ScrolledWin.$r.val configure -fg $tixOption(fg) -bg $tixOption(bg) + + if {![pref get gdb/mode]} { + $itk_interior.m.reg entryconfigure 0 -state normal -command "$this edit $r" + } + $itk_interior.m.reg entryconfigure 2 -state normal \ + -command "$this delete_from_display_list $r" + for {set i 0} {$i < 6} {incr i} { + $itk_interior.m.reg.format entryconfigure $i -state normal \ + -variable reg_display($r,format) + } + focus -force $ScrolledWin.$r + set selected $r +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: dimensions - determine square-like dimensions for +# register window +# ------------------------------------------------------------------ +body RegWin::dimensions {} { + set rows 16 + # set rows [expr int(floor(sqrt($num_regs)))] + set cols [expr {int(ceil(sqrt($num_regs)))}] + + return [list $rows $cols] +} + +# ------------------------------------------------------------------------------ +# NAME: +# private method RegWin::fixLength +# +# SYNOPSIS: +# fixLength {s size where} +# +# DESC: +# Makes a string into a fixed-length string, inserting spaces as +# necessary. If 'where' is "left" spaces will be added to the left, +# if 'where' is "right" spaces will be added to the right. +# ARGS: +# s - input string +# size - size of string to output +# where - "left" or "right" +# +# RETURNS: +# Padded string of length 'size' +# +# NOTES: +# This should really be a proc, not a method. +# ------------------------------------------------------------------------------ +body RegWin::fixLength {s size where} { + set blank " " + set len [string length $s] + set bl [expr {$size - $len}] + set b [string range $blank 0 $bl] + + switch $where { + left { set fl "$s$b"} + right { set fl "$b$s"} + } + return $fl +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: but3 - generate and display a popup window on button 3 +# over the register value +# ------------------------------------------------------------------ +body RegWin::but3 {rn X Y} { + global reg_display max_regs + + if {!$Running} { + $Menu delete 0 end + $Menu add command -label $reg_display($rn,name) -state disabled + $Menu add separator + $Menu add radio -label "Hex" -command "$this update" \ + -value x -variable reg_display($rn,format) + $Menu add radio -label "Decimal" -command "$this update" \ + -value d -variable reg_display($rn,format) + $Menu add radio -label "Natural" -command "$this update" \ + -value {} -variable reg_display($rn,format) + $Menu add radio -label "Binary" -command "$this update" \ + -value t -variable reg_display($rn,format) -underline 0 + $Menu add radio -label "Octal" -command "$this update" \ + -value o -variable reg_display($rn,format) + $Menu add radio -label "Raw" -command "$this update" \ + -value r -variable reg_display($rn,format) + $Menu add separator + $Menu add command -command "$this delete_from_display_list $rn" \ + -label "Remove $reg_display($rn,name) from Display" + if {$max_regs != $num_regs} { + $Menu add separator + $Menu add command -command "$this display_all" \ + -label "Display all registers" + } + tk_popup $Menu $X $Y + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: display_all - add all registers to the display list +# ------------------------------------------------------------------ +body RegWin::display_all {} { + init_reg_display_vars + $itk_interior.m.reg entryconfigure 4 -state disabled + reconfig +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: delete_from_display_list - remove a register from the +# display list +# ------------------------------------------------------------------ +body RegWin::delete_from_display_list {rn} { + global reg_display max_regs + set reg_display($rn,line) 0 + set reg_display_list {} + set rn 0 + set i 0 + while {$rn < $max_regs} { + if {$reg_display($rn,line) > 0} { + lappend reg_display_list $rn + incr i + set reg_display($rn,line) $i + } + incr rn + } + set num_regs $i + reconfig + $itk_interior.m.reg entryconfigure 4 -state normal +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: edit - edit a cell +# ------------------------------------------------------------------ +body RegWin::edit {r} { + global reg_display + if {$Running} { return } + unedit + + set Editing $r + set txt [$ScrolledWin.$r.val cget -text] + set len [string length $txt] + set entry [entry $ScrolledWin.$r.ent -width $len -bd 0 -font src-font] + $entry insert 0 $txt + + grid remove $ScrolledWin.$r.val + grid $entry -row 0 -col 1 + bind $entry <Return> "$this acceptEdit $r" + bind $entry <Escape> "$this unedit" + $entry selection to end + focus $entry +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: acceptEdit - callback invoked when enter key pressed +# in an editing entry +# ------------------------------------------------------------------ +body RegWin::acceptEdit {r} { + global reg_display + + set value [string trimleft [$ScrolledWin.$r.ent get]] + debug "value=${value}=" + if {$value == ""} { + set value 0 + } + if {[catch {gdb_cmd "set \$$reg_display($r,name)=$value"} result]} { + tk_messageBox -icon error -type ok -message $result \ + -title "Error in Expression" -parent $this + focus $ScrolledWin.$r.ent + $ScrolledWin.$r.ent selection to end + } else { + unedit + gdbtk_update + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: unedit - clear any editing entry on the screen +# ------------------------------------------------------------------ +body RegWin::unedit {} { + if {$Editing != -1} { + destroy $ScrolledWin.$Editing.ent + + # Fill the entry with the old label, updating value + grid $ScrolledWin.$Editing.val -column 1 -row 0 + focus -force $ScrolledWin.$Editing + set Editing -1 + update + } +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: update - update widget when PC changes +# ------------------------------------------------------------------ +body RegWin::update {} { + global reg_display + debug "START REGISTER UPDATE CALLBACK" + if {$reg_display_list == "" + || [catch {eval gdb_changed_register_list $reg_display_list} changed_reg_list]} { + set changed_reg_list {} + } + + set vmax 0 + foreach r $reg_display_list { + if {[catch {gdb_fetch_registers $reg_display($r,format) $r} values($r)]} { + set values($r) "" + } else { + set values($r) [string trim $values($r) \ ] + } + set l [string length $values($r)] + if {$l > $vmax} { + set vmax $l + } + } + + foreach r $reg_display_list { + if {[lsearch -exact $changed_reg_list $r] != -1} { + set fg $HighlightForeground + } else { + set fg $NormalForeground + } + $ScrolledWin.$r.val configure -text [fixLength $values($r) $vmax right] \ + -fg $fg + } + debug "END REGISTER UPDATE CALLBACK" +} + +body RegWin::idle {} { + [winfo toplevel $itk_interior] configure -cursor {} + set Running 0 +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body RegWin::reconfig {} { + if {$reg_names_dirty} { + init_reg_display_vars + } + destroy $Menu $itk_interior.g $itk_interior.scrolled $itk_interior.m + gdbtk_busy + build_win + gdbtk_idle +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: busy - gdb_busy_hook +# ------------------------------------------------------------------ +body RegWin::busy {} { + # Cancel edits + unedit + + # Fencepost + set Running 1 + + # cursor + [winfo toplevel $itk_interior] configure -cursor watch +} diff --git a/gdb/gdbtk/library/regwin.ith b/gdb/gdbtk/library/regwin.ith new file mode 100644 index 00000000000..e779f85b0f8 --- /dev/null +++ b/gdb/gdbtk/library/regwin.ith @@ -0,0 +1,68 @@ +# Register display window class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class RegWin { + inherit EmbeddedWin GDBWin + + private { + variable reg_display_list {} + variable num_regs 0 + variable nRows + variable nCols + variable changed_reg_list {} + variable oldValue + variable ScrolledWin + variable Menu + variable Editing -1 + variable selected -1 + variable mbar 1 + variable reg_names_dirty 0 + variable Running 0 + + common HighlightForeground {} + common NormalForeground {} + + method init_reg_display_vars {args} + method handle_set_hook {var val} + method disassembly_changed {} + method dimensions {} + method fixLength {s size where} + method build_win {} + } + + public { + proc save_reg_display_vars {} + + method constructor {args} + method destructor {} + method reg_select_up {} + method reg_select_down {} + method reg_select_right {} + method reg_select_left {} + method reg_select { r } + method but3 {rn X Y} + method display_all {} + method delete_from_display_list {rn} + method edit {r} + method acceptEdit {r} + method unedit {} + method update {} + method idle {} + method reconfig {} + method busy {} + } + + +} + diff --git a/gdb/gdbtk/library/srcbar.tcl b/gdb/gdbtk/library/srcbar.tcl new file mode 100644 index 00000000000..93177521884 --- /dev/null +++ b/gdb/gdbtk/library/srcbar.tcl @@ -0,0 +1,643 @@ +# GDBSrcBar +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements a toolbar that is attached to a source window. +# +# PUBLIC ATTRIBUTES: +# +# +# METHODS: +# +# config ....... used to change public attributes +# +# PRIVATE METHODS +# +# X11 OPTION DATABASE ATTRIBUTES +# +# +# ---------------------------------------------------------------------- + +class GDBSrcBar { + inherit GDBToolBar + + # ------------------------------------------------------------------ + # CONSTRUCTOR - create widget + # ------------------------------------------------------------------ + constructor {src args} { + GDBToolBar::constructor $src + } { + eval itk_initialize $args + add_hook gdb_trace_find_hook "$this trace_find_hook" + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - destroy window containing widget + # ------------------------------------------------------------------ + destructor { + global GDBSrcBar_state + unset GDBSrcBar_state($this) + remove_hook gdb_trace_find_hook "$this trace_find_hook" + } + + # + # PUBLIC DATA + # + + # This is the command that should be run when the `update' + # checkbutton is toggled. The current value of the checkbutton is + # appended to the command. + public variable updatecommand {} + + # This controls whether the `update' checkbutton is turned on or + # off. + public variable updatevalue 0 { + global GDBSrcBar_state + ::set GDBSrcBar_state($this) $updatevalue + } + + # This holds the text that is shown in the address label. + public variable address {} { + if {$ButtonFrame != "" && [winfo exists $ButtonFrame.addr]} { + $ButtonFrame.addr configure -text $address -font src-font + } + } + + # This holds the text that is shown in the line label. + public variable line {} { + if {$ButtonFrame != "" && [winfo exists $ButtonFrame.line]} { + $ButtonFrame.line configure -text $line + } + } + + # This holds the source window's display mode. Valid values are + # SOURCE, ASSEMBLY, SRC+ASM, and MIXED. + public variable displaymode SOURCE { + if {$ButtonFrame != ""} { + _set_stepi + } + } + + # This is true if the inferior is running, or false if it is + # stopped. + public variable runstop normal { + if {$ButtonFrame != ""} { + _set_runstop + } + } + + # The next three determine the state of the application when Tracing is enabled. + + public variable Tracing 0 ;# Is tracing enabled for this gdb? + public variable Browsing 0 ;# Are we currently browsing a trace experiment? + public variable Collecting 0 ;# Are we currently collecting a trace experiment? + + # ------------------------------------------------------------------ + # METHOD: create_menu_items - Add some menu items to the menubar. + # Returns 1 if any items added. + # This overrides the method in GDBToolBar. + # ------------------------------------------------------------------ + public method create_menu_items {} { + global enable_external_editor tcl_platform + + set m [new_menu file "File" 0] + + if {[info exists enable_external_editor] && $enable_external_editor} { + add_menu_command None "Edit Source" \ + [list $this _apply_source edit] + } + add_menu_command Other "Open..." \ + "_open_file" -underline 0 -accelerator "Ctrl+O" + + add_menu_command Other "Source..." \ + "source_file" -underline 0 + + add_menu_separator + + if {$tcl_platform(platform) == "windows"} { + add_menu_command None "Page Setup..." \ + [format { + set top %s + ide_winprint page_setup -parent $top + } [winfo toplevel [namespace tail $this]]] \ + -underline 8 + add_menu_command None "Print Source..." \ + "$this _apply_source print" \ + -underline 0 -accelerator "Ctrl+P" + add_menu_separator + + } + + add_menu_command Other "Target Settings..." "set_target_name" \ + -underline 0 + add_menu_separator + add_menu_command None "Exit" gdbtk_quit -underline 1 + + create_run_menu + + create_view_menu + + if {[pref get gdb/control_target]} { + create_control_menu + + } + + if {[pref get gdb/mode]} { + create_trace_menu + } + + new_menu pref "Preferences" 0 + + add_menu_command Other "Global..." \ + "ManagedWin::open GlobalPref -transient" -underline 0 + + add_menu_command Other "Source..." \ + "ManagedWin::open SrcPref -transient" -underline 0 + + create_help_menu + return 1 + } + + # ------------------------------------------------------------------ + # METHOD: create_buttons - Add some buttons to the toolbar. Returns + # list of buttons in form acceptable to + # standard_toolbar. + # This overrides the method in GDBToolBar. + # ------------------------------------------------------------------ + public method create_buttons {} { + global enable_external_editor + + add_button stop None {} {} + _set_runstop + + if {[pref get gdb/mode]} { + add_button tstop Control [list $this do_tstop] "Start Collection" \ + -image Movie_on_img + + add_button view Other [list $this set_control_mode 1] \ + "Switch to Browse Mode" -image watch_movie_img + + add_button_separator + + } + + if {[pref get gdb/control_target]} { + create_control_buttons + if {[pref get gdb/mode]} { + create_trace_buttons 0 + } + } elseif {[get pref gdb/mode]} { + + # + # If we don't control the target, then we might as well + # put a copy of the trace controls on the source window. + # + create_trace_buttons 1 + } + + add_button_separator + + create_window_buttons + + # Random bits of obscurity... + bind $Buttons(reg) <Button-3> "ManagedWin::open RegWin -force" + bind $Buttons(mem) <Button-3> "ManagedWin::open MemWin -force" + bind $Buttons(watch) <Button-3> "ManagedWin::open WatchWin -force" + bind $Buttons(vars) <Button-3> "ManagedWin::open LocalsWin -force" + + add_button_separator + + if {[info exists enable_external_editor] && $enable_external_editor} { + add_button edit Other [list $this _apply_source edit] "Edit Source" \ + -image edit_img + + add_button_separator + } + + add_label addr $address "Address" -width 10 -relief sunken -bd 1 -anchor e \ + -font src-font + + add_label line $line "Line Number" -width 6 -relief sunken -bd 1 -anchor e \ + -font src-font + + button_right_justify + + create_stack_buttons + + # This feature has been disabled for now. + # checkbutton $ButtonFrame.upd -command "$this _toggle_updates" \ + # -variable GDBSrcBar_state($this) + # lappend button_list $ButtonFrame.upd + # global GDBSrcBar_state + # ::set GDBSrcBar_state($this) $updatevalue + # balloon register $ButtonFrame.upd "Toggle Window Updates" + + } + + # ------------------------------------------------------------------ + # METHOD: _toggle_updates - Run when the update checkbutton is + # toggled. Private method. + # ------------------------------------------------------------------ + public method _toggle_updates {} { + global GDBSrcBar_state + if {$updatecommand != ""} { + uplevel \#0 $updatecommand $GDBSrcBar_state($this) + } + } + + # ------------------------------------------------------------------ + # METHOD: cancel_download + # ------------------------------------------------------------------ + public method cancel_download {} { + global download_dialog download_cancel_ok + + if {"$download_dialog" != ""} { + $download_dialog cancel + } else { + set download_cancel_ok 1 + } + } + + # ------------------------------------------------------------------ + # METHOD: create_run_menu - Creates the standard run menu, + # or reconfigures it if it already exists. + # ------------------------------------------------------------------ + + method create_run_menu {} { + + if {![menu_exists Run]} { + set run_menu [new_menu run "Run" 0] + } else { + set run_menu [clear_menu Run] + } + + set is_native [TargetSelection::native_debugging] + + # If we are on a Unix target, put in the attach options. "ps" doesn't + # give me the Windows PID yet, and the attach also seems flakey, so + # I will hold off on the Windows implementation for now. + + if {$is_native} { + if {[string compare $::tcl_platform(platform) windows] != 0} { + add_menu_command Attach "Attach to process" \ + [code $this do_attach $run_menu] \ + -underline 0 -accelerator "Ctrl+A" + } + } else { + add_menu_command Other "Connect to target" \ + "$this do_connect $run_menu" -underline 0 + } + + if {[pref get gdb/control_target]} { + if {!$is_native} { + add_menu_command Other "Download" Download::download_it \ + -underline 0 -accelerator "Ctrl+D" + } + add_menu_command Other "Run" [code $source inferior run] -underline 0 \ + -accelerator R + } + + if {$is_native} { + if {[string compare $::tcl_platform(platform) windows] != 0} { + add_menu_command Detach "Detach" [code $this do_detach $run_menu] \ + -underline 0 -state disabled + } + } else { + add_menu_command Other "Disconnect" \ + [code $this do_disconnect $run_menu] -underline 0 -state disabled + } + + if {$is_native} { + add_menu_separator + add_menu_command Control "Kill" [code $this do_kill $run_menu] \ + -underline 0 -state disabled + } + + if { [pref get gdb/mode] } { + add_menu_separator + add_menu_command Other "Start collection" "$this do_tstop" \ + -underline 0 -accelerator "Ctrl+B" + + add_menu_command Other "Stop collection" "$this do_tstop" \ + -underline 0 -accelerator "Ctrl+E" -state disabled + } + + } + + # ------------------------------------------------------------------ + # METHOD: create_stack_buttons - Creates the up down bottom stack buttons + # ------------------------------------------------------------------ + + method create_stack_buttons {} { + + add_button down {Trace Control} [list $this _apply_source stack down] \ + "Down Stack Frame" -image down_img + + add_button up {Trace Control} [list $this _apply_source stack up] \ + "Up Stack Frame" -image up_img + + add_button bottom {Trace Control} [list $this _apply_source stack bottom] \ + "Go to Bottom of Stack" -image bottom_img + + } + + # ------------------------------------------------------------------ + # METHOD: _set_runstop - Set state of run/stop button. + # ------------------------------------------------------------------ + public method _set_runstop {} { + switch $runstop { + busy { + $ButtonFrame.stop configure -state disabled + } + downloading { + $ButtonFrame.stop configure -state normal -image stop_img \ + -command [code $this cancel_download] + balloon register $ButtonFrame.stop "Stop" + } + running { + $ButtonFrame.stop configure -state normal -image stop_img \ + -command [code $source inferior stop] + balloon register $ButtonFrame.stop "Stop" + + } + normal { + $ButtonFrame.stop configure -state normal -image run_img \ + -command [code $source inferior run] + balloon register $ButtonFrame.stop "Run (R)" + } + default { + debug "SrcBar::_set_runstop - unknown state $runstop ($running)" + } + } + } + + + # ------------------------------------------------------------------ + # METHOD: _set_stepi - Set state of stepi/nexti buttons. + # ------------------------------------------------------------------ + public method _set_stepi {} { + + # Only do this in synchronous mode + if {!$Tracing} { + # In source-only mode, disable these buttons. Otherwise, enable + # them. + if {$displaymode == "SOURCE"} { + set state disabled + } else { + set state normal + } + $ButtonFrame.stepi configure -state $state + $ButtonFrame.nexti configure -state $state + } + } + + # ------------------------------------------------------------------ + # METHOD: _apply_source - Forward some method call to the source window. + # ------------------------------------------------------------------ + public method _apply_source {args} { + if {$source != ""} { + eval $source $args + } + } + + # ------------------------------------------------------------------ + # METHOD: trace_find_hook - response to the tfind command. If the + # command puts us in a new mode, then switch modes... + # ------------------------------------------------------------------ + method trace_find_hook {mode from_tty} { + debug "in trace_find_hook, mode: $mode, from_tty: $from_tty, Browsing: $Browsing" + if {[string compare $mode -1] == 0} { + if {$Browsing} { + set_control_mode 0 + } + } else { + if {!$Browsing} { + set_control_mode 1 + } + } + } + # ------------------------------------------------------------------ + # METHOD: set_control_mode - sets up the srcbar for browsing + # a trace experiment. + # mode: 1 => browse mode + # 0 => control mode + # ------------------------------------------------------------------ + method set_control_mode {mode} { + debug "set_control_mode called with mode $mode" + if {$mode} { + set Browsing 1 + $Buttons(view) configure -image run_expt_img -command "$this set_control_mode 0" + balloon register $Buttons(view) "Switch to Control mode" + # Now swap out the buttons... + swap_button_lists $Trace_control_buttons $Run_control_buttons + enable_ui 1 + } else { + if {$Browsing} { + tfind_cmd {tfind none} + } + set Browsing 0 + $Buttons(view) configure -image watch_movie_img -command "$this set_control_mode 1" + balloon register $Buttons(view) "Switch to Browse mode" + # Now swap out the buttons... + swap_button_lists $Run_control_buttons $Trace_control_buttons + enable_ui 1 + } + run_hooks control_mode_hook $Browsing + } + + + # ------------------------------------------------------------------ + # METHOD: reconfig - reconfigure the srcbar + # ------------------------------------------------------------------ + public method reconfig {} { + _load_src_images 1 + GDBToolBar::reconfig + } + + # ------------------------------------------------------------------ + # METHOD: do_attach: attach to a running target + # ------------------------------------------------------------------ + method do_attach {menu} { + ManagedWin::open_dlg AttachDlg ;#-transient + + debug "ManagedWin got [AttachDlg::last_button] [AttachDlg::pid]" + + if {[AttachDlg::last_button]} { + set pid [AttachDlg::pid] + set symbol_file [AttachDlg::symbol_file] + if {![_open_file $symbol_file]} { + ManagedWin::open WarningDlg -transient \ + -message "Could not load symbols from $symbol_file." + return + } + + if {[catch {gdb_cmd "attach $pid"} result]} { + ManagedWin::open WarningDlg -transient \ + -message [list "Could not attach to $pid:\n$result"] + return + } + + } + + } + + # ------------------------------------------------------------------ + # METHOD: do_detach: detach from a running target + # ------------------------------------------------------------------ + method do_detach {menu} { + ::disconnect + gdbtk_idle + } + + # ------------------------------------------------------------------ + # METHOD: do_kill: kill the current target + # ------------------------------------------------------------------ + method do_kill {menu} { + gdb_cmd "kill" + run_hooks gdb_no_inferior_hook + } + + # ------------------------------------------------------------------ + # METHOD: do_connect: connect to a remote target + # in asynch mode if async is 1 + # ------------------------------------------------------------------ + method do_connect {menu {async 0}} { + global file_done + + debug "do_connect: menu=$menu async=$async" + + gdbtk_busy + + set result [gdbtk_attach_target] + switch $result { + ATTACH_ERROR { + set successful 0 + } + + ATTACH_TARGET_CHANGED { + if {[pref get gdb/load/check] && $file_done} { + set err [catch {gdb_cmd "compare-sections"} errTxt] + if {$err} { + set successful 0 + tk_messageBox -title "Error" -message $errTxt \ + -icon error -type ok + break + } + } + + tk_messageBox -title "GDB" -message "Successfully connected" \ + -icon info -type ok + set successful 1 + } + + ATTACH_CANCELED { + tk_messageBox -title "GDB" -message "Connection Canceled" -icon info \ + -type ok + set successful 0 + } + + ATTACH_TARGET_UNCHANGED { + tk_messageBox -title "GDB" -message "Successfully connected" \ + -icon info -type ok + set successful 1 + } + + default { + dbug E "Unhandled response from gdbtk_attach_target: \"$result\"" + set successful 0 + } + } + + gdbtk_idle + + if {$successful} { + $menu entryconfigure "Connect to target" -state disabled + $menu entryconfigure "Disconnect" -state normal + } else { + $menu entryconfigure "Connect to target" -state normal + $menu entryconfigure "Disconnect" -state disabled + } + + # Whenever we attach, we need to do an update + gdbtk_update + } + + + # ------------------------------------------------------------------ + # METHOD: do_disconnect: disconnect from a remote target + # in asynch mode if async is 1. + # + # ------------------------------------------------------------------ + method do_disconnect {menu {async 0}} { + debug "$menu $async" + # + # For now, these are the same, but they might be different... + # + + disconnect $async + + $menu entryconfigure "Connect to target" -state normal + $menu entryconfigure "Disconnect" -state disabled + } + + # ------------------------------------------------------------------ + # METHOD: do_tstop: Change the GUI state, then do the tstop or + # tstart command, whichever is appropriate. + # + # ------------------------------------------------------------------ + method do_tstop {} { + debug "do_tstop called... Collecting is $Collecting" + + if {!$Collecting} { + # + # Start the trace experiment + # + + if {$Browsing} { + set ret [tk_MessageBox -title "Warning" -message \ +"You are currently browsing a trace experiment. +This command will clear the results of that experiment. +Do you want to continue?" \ + -icon warning -type okcancel -default ok] + if {[string compare $ret cancel] == 0} { + return + } + set_control_mode 1 + } + if {[tstart]} { + $Buttons(tstop) configure -image Movie_off_img + balloon register $Buttons(tstop) "End Collection" + set Collecting 1 + } else { + tk_messageBox -title Error -message "Error downloading tracepoint info" \ + -icon error -type ok + } + } else { + # + # Stop the trace experiment + # + + if {[tstop]} { + $Buttons(tstop) configure -image Movie_on_img + balloon register $Buttons(tstop) "Start Collection" + set Collecting 0 + } + } + } + + # + # PROTECTED DATA + # + common menu_titles +} diff --git a/gdb/gdbtk/library/srcpref.itb b/gdb/gdbtk/library/srcpref.itb new file mode 100644 index 00000000000..374a32c7fc1 --- /dev/null +++ b/gdb/gdbtk/library/srcpref.itb @@ -0,0 +1,246 @@ +# Source preferences dialog for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new source preferences window +# ------------------------------------------------------------------ +body SrcPref::constructor {args} { + window_name "Source Preferences" + + build_win + set saved(gdb/src/PC_TAG) [pref get gdb/src/PC_TAG] + set saved(gdb/src/STACK_TAG) [pref get gdb/src/STACK_TAG] + set saved(gdb/src/BROWSE_TAG) [pref get gdb/src/BROWSE_TAG] + set saved(gdb/src/run_attach) [pref get gdb/src/run_attach] + set saved(gdb/src/run_load) [pref get gdb/src/run_load] + set saved(gdb/src/run_run) [pref get gdb/src/run_run] + set saved(gdb/src/run_cont) [pref get gdb/src/run_cont] + set saved(gdb/src/bp_fg) [pref get gdb/src/bp_fg] + set saved(gdb/src/temp_bp_fg) [pref get gdb/src/temp_bp_fg] + set saved(gdb/src/trace_fg) [pref get gdb/src/trace_fg] + set saved(gdb/src/thread_fg) [pref get gdb/src/thread_fg] + set saved(gdb/src/variableBalloons) [pref get gdb/src/variableBalloons] + set saved(gdb/src/source2_fg) [pref get gdb/src/source2_fg] + set saved(gdb/src/tab_size) [pref get gdb/src/tab_size] + set saved(gdb/mode) [pref get gdb/mode] +} + +# ------------------------------------------------------------------ +# METHOD: build_win - build the dialog +# ------------------------------------------------------------------ +body SrcPref::build_win {} { + frame $itk_interior.f + frame $itk_interior.f.a + frame $itk_interior.f.b + set f $itk_interior.f.a + + # Colors frame + Labelledframe $f.colors -anchor nw -text {Colors} + set w [$f.colors get_frame] + + set color [pref get gdb/src/PC_TAG] + label $w.pcl -text {PC} + button $w.pcb -text { } -activebackground $color -bg $color \ + -command [code $this _pick $color $w.pcb PC_TAG] + + set color [pref get gdb/src/STACK_TAG] + label $w.stl -text {Stack} + button $w.stb -text { } -activebackground $color -bg $color \ + -command [code $this _pick $color $w.stb STACK_TAG] + + set color [pref get gdb/src/BROWSE_TAG] + label $w.brl -text {Browse} + button $w.brb -text { } -activebackground $color -bg $color\ + -command [code $this _pick $color $w.brb BROWSE_TAG] + + set color [pref get gdb/src/source2_fg] + label $w.s2l -text {Mixed Source} + button $w.s2b -text { } -activebackground $color -bg $color \ + -command [code $this _pick $color $w.s2b source2_fg] + + set color [pref get gdb/src/bp_fg] + label $w.nbpl -text {Normal Breakpoint} + button $w.nbpb -text { } -activebackground $color -bg $color\ + -command [code $this _pick $color $w.nbpb bp_fg] + + set color [pref get gdb/src/temp_bp_fg] + label $w.tbpl -text {Temporary Breakpoint} + button $w.tbpb -text { } -activebackground $color -bg $color \ + -command [code $this _pick $color $w.tbpb temp_bp_fg] + + set color [pref get gdb/src/thread_fg] + label $w.dbpl -text {Thread Breakpoint} + button $w.dbpb -text { } -activebackground $color -bg $color \ + -command [code $this _pick $color $w.dbpb thread_fg] + + set color [pref get gdb/src/trace_fg] + label $w.tpl -text {Tracepoint} + button $w.tpb -text { } -activebackground $color -bg $color \ + -command [code $this _pick $color $w.tpb trace_fg] + + grid $w.pcl $w.pcb $w.nbpl $w.nbpb -padx 10 -pady 2 -sticky w + grid $w.stl $w.stb $w.tbpl $w.tbpb -padx 10 -pady 2 -sticky w + grid $w.brl $w.brb $w.dbpl $w.dbpb -padx 10 -pady 2 -sticky w + grid $w.s2l $w.s2b $w.tpl $w.tpb -padx 10 -pady 2 -sticky w + + frame $f.rmv + + # Debug Mode frame + Labelledframe $f.rmv.mode -anchor nw -text "Mouse Button-1 Behavior" + set w [$f.rmv.mode get_frame] + set var [pref varname gdb/B1_behavior] + if {[pref get gdb/mode]} { + set state normal + } else { + pref set gdb/B1_behavior 1 + set state disabled + } + + radiobutton $w.async -text "Set/Clear Tracepoints" -variable $var \ + -value 0 -state $state + radiobutton $w.sync -text "Set/Clear Breakpoints" -variable $var \ + -value 1 -state $state + + pack $w.async $w.sync -side top + + # Variable Balloons + Labelledframe $f.rmv.var -anchor nw -text "Variable Balloons" + set w [$f.rmv.var get_frame] + set var [pref varname gdb/src/variableBalloons] + radiobutton $w.var_on -text "On " -variable $var -value 1 + radiobutton $w.var_off -text "Off" -variable $var -value 0 + pack $w.var_on $w.var_off -side top + grid $f.rmv.mode -sticky nsew -pady 5 -row 0 -col 0 + grid $f.rmv.var -sticky nsew -pady 5 -row 0 -col 2 + grid columnconfigure $f.rmv 0 -weight 1 + grid columnconfigure $f.rmv 1 -minsize 4 + grid columnconfigure $f.rmv 2 -weight 1 + grid rowconfigure $f.rmv 0 -weight 1 + + + frame $f.x + # Tab size + tixControl $f.x.size -label "Tab Size" -integer true -max 16 -min 1 \ + -variable [pref varname gdb/src/tab_size] \ + -options { entry.width 2 entry.font src-font} + + # Linenumbers + # commented out because this option isn't really useful +# checkbutton $f.x.linenum -text "Line Numbers" \ +# -variable [pref varname gdb/src/linenums] +# pack $f.x.size $f.x.linenum -side left -padx 5 -pady 5 + pack $f.x.size -side left -padx 5 -pady 5 + + # Disassembly flavor - We tell whether this architecture supports + # the flag by checking whether the flag exists. + + set have_disassembly_flavor 0 + set vals [list_disassembly_flavors] + if {[llength $vals] != 0} { + set have_disassembly_flavor 1 + frame $f.dis + label $f.dis.l -text "Disassembly Flavor: " + combobox::combobox $f.dis.combo -maxheight 15 -width 15 -font src-font -editable 0 \ + -command [code $this set_flavor] + + foreach elem $vals { + $f.dis.combo list insert end $elem + } + + set current_disassembly_flavor [get_disassembly_flavor] + $f.dis.combo entryset $current_disassembly_flavor + + pack $f.dis.l -side left + pack $f.dis.combo -side left -padx 4 + + } else { + set current_disassembly_flavor "" + } + + pack $f.colors -fill both -expand 1 + pack $f.rmv -fill both -expand yes + pack $f.x -fill x -expand yes + + if {$have_disassembly_flavor} { + pack $f.dis -side top -fill x -padx 4 + } + + button $itk_interior.f.b.ok -text OK -width 7 -underline 0 -command [code $this _save] + button $itk_interior.f.b.apply -text Apply -width 7 -underline 0 -command [code $this _apply] + button $itk_interior.f.b.quit -text Cancel -width 7 -underline 0 -command [code $this _cancel] + standard_button_box $itk_interior.f.b + pack $itk_interior.f.a $itk_interior.f.b $itk_interior.f -expand yes -fill both -padx 5 -pady 5 +} + +# ------------------------------------------------------------------ +# METHOD: apply - apply changes +# ------------------------------------------------------------------ +body SrcPref::_apply {} { + if {$current_disassembly_flavor != ""} { + gdb_cmd "set disassembly-flavor $current_disassembly_flavor" + pref set gdb/src/disassembly-flavor $current_disassembly_flavor + } + ManagedWin::restart +} + +# ------------------------------------------------------------------ +# METHOD: cancel +# ------------------------------------------------------------------ +body SrcPref::_cancel {} { + set any_changed 0 + + foreach elem [array names _saved] { + set cur_val [pref get $elem] + if {[string compare $cur_val $_saved($elem)] != 0} { + set any_changed 1 + pref set $elem $_saved($elem) + } + } + + if {$any_changed} { + _save + } else { + unpost + } +} + +# ------------------------------------------------------------------ +# METHOD: save - apply changes and quit +# ------------------------------------------------------------------ +body SrcPref::_save {} { + _apply + unpost +} + +# ------------------------------------------------------------------ +# METHOD: set_flavor - sets the disassembly flavor. The set disassembly-flavor +# gdb command is already known to exist, so I don't have to check... +# ------------------------------------------------------------------ +body SrcPref::set_flavor {w new_mode} { + $w entryset $new_mode + set current_disassembly_flavor $new_mode +} + + +# ------------------------------------------------------------------ +# METHOD: pick - pick colors +# ------------------------------------------------------------------ +body SrcPref::_pick {color win tag} { + set new_color [tk_chooseColor -initialcolor $color -title "Choose color"] + if {$new_color != $color && $new_color != {}} { + pref set gdb/src/$tag $new_color + $win configure -activebackground $new_color -bg $new_color + } +} + diff --git a/gdb/gdbtk/library/srcpref.ith b/gdb/gdbtk/library/srcpref.ith new file mode 100644 index 00000000000..0c45e1ef407 --- /dev/null +++ b/gdb/gdbtk/library/srcpref.ith @@ -0,0 +1,34 @@ +# Source preferences dialog class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class SrcPref { + inherit ManagedWin ModalDialog + + private { + variable _saved ;# These are the saved values... + variable current_disassembly_flavor "" + + method build_win {} + method _apply {} + method _cancel {} + method _save {} + method set_flavor {w new_mode} + method _pick {color win tag} + } + + public { + method constructor {args} + } +} + diff --git a/gdb/gdbtk/library/srctextwin.itb b/gdb/gdbtk/library/srctextwin.itb new file mode 100644 index 00000000000..5edb7a34e13 --- /dev/null +++ b/gdb/gdbtk/library/srctextwin.itb @@ -0,0 +1,2683 @@ + # Paned text widget for source code, for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements the paned text widget with the source code in it. +# This widget is typically embedded in a SrcWin widget. +# +# ---------------------------------------------------------------------- + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new source text window +# ------------------------------------------------------------------ +body SrcTextWin::constructor {args} { + eval itk_initialize $args + set top [winfo toplevel $itk_interior] + if {$parent == {}} { + set parent [winfo parent $itk_interior] + } + + if {![info exists break_images(bp)]} { + set size [font measure [pref get gdb/src/font] "W"] + set break_images(bp) [makeBreakDot $size \ + [pref get gdb/src/bp_fg]] + set break_images(temp_bp) [makeBreakDot $size \ + [pref get gdb/src/temp_bp_fg]] + set break_images(disabled_bp) [makeBreakDot $size \ + [pref get gdb/src/disabled_fg]] + set break_images(tp) [makeBreakDot $size \ + [pref get gdb/src/trace_fg]] + set break_images(thread_bp) [makeBreakDot $size \ + [pref get gdb/src/thread_fg]] + set break_images(bp_and_tp) [makeBreakDot $size \ + [list [pref get gdb/src/trace_fg] \ + [pref get gdb/src/bp_fg]]] + } + + if {$ignore_var_balloons} { + set UseVariableBalloons 0 + } else { + set UseVariableBalloons [pref get gdb/src/variableBalloons] + } + + set Linenums [pref get gdb/src/linenums] + + #Initialize state variables + _initialize_srctextwin + + build_popups + build_win + + # add hooks + add_hook gdb_breakpoint_change_hook "$this bp" + + if {$Tracing} { + add_hook control_mode_hook "$this set_control_mode" + add_hook gdb_trace_find_hook "$this trace_find_hook" + } + + if {[get_disassembly_flavor] != ""} { + add_hook gdb_set_hook [code $this handle_set_hook] + } + + if {$UseVariableBalloons} { + add_hook gdb_idle_hook "$this updateBalloon" + } + global ${this}_balloon + trace variable ${this}_balloon w "$this trace_help" + +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body SrcTextWin::destructor {} { + remove_hook gdb_breakpoint_change_hook "$this bp" + if {$Tracing} { + remove_hook control_mode_hook "$this set_control_mode" + } + if {$UseVariableBalloons} { + remove_hook gdb_idle_hook "$this updateBalloon" + } + if {[get_disassembly_flavor] != ""} { + remove_hook gdb_set_hook [code $this handle_set_hook] + } +} + +# ------------------------------------------------------------------ +# METHOD: trace_find_hook - response to the tfind command. All we +# need to do here is to remove the trace tags, if we are exiting +# trace mode +# ------------------------------------------------------------------ +body SrcTextWin::trace_find_hook {mode from_tty} { + if {[string compare $mode -1] == 0} { + if {$Browsing} { + $twin tag remove STACK_TAG 1.0 end + } + } +} + +# ------------------------------------------------------------------ +# METHOD: set_control_mode- switches the src window between +# browsing -> mode = 1 +# controlling -> mode = 0 +# ------------------------------------------------------------------ +body SrcTextWin::set_control_mode {mode} { +# debug "Setting control mode of $twin to $mode" + if {$mode} { + set Browsing 1 + } else { + set Browsing 0 + } + + switch $current(mode) { + SOURCE { + config_win $twin + } + ASSEMBLY { + config_win $twin A + } + MIXED { + config_win $twin M + } + SRC+ASM { + config_win $twin + config_win $bwin A + } + } + +} + +# ------------------------------------------------------------------ +# METHOD: build_popups - build the popups for the source window(s) +# ------------------------------------------------------------------ +# +# The popups array holds the data for the breakpoint & tracepoint popup menus. +# The elements are: +# Menus: +# break_rgn - the popup for clicking in a bare break region +# bp - the popup for clicking on a set breakpoint +# tp - the popup for clicking on a set tracepoint +# bp_and_tp - the popup for clicking on the break_region when the +# line contains both a bp & a tp +# source - the popup for clicking on the source region of the window +# +# State: +# saved_y - the y value of the mouse click that posted the popup +# saved_win- the Tk window which recieved the posting click +# +# Disable info: +# run_disabled - a list of {menu entry} pairs for all the menus that +# should be disabled when you are not running +# browse_disabled - a similar list for menus that should be disabled +# when you are browsing a trace expt. +# +body SrcTextWin::build_popups {} { + + set popups(bp) $itk_interior.bp_menu + set popups(tp) $itk_interior.tp_menu + set popups(bp_and_tp) $itk_interior.tp_bp_menu + set popups(tp_browse) $itk_interior.tp_browse_menu + set popups(break_rgn) $itk_interior.break_menu + set popups(source) $itk_interior.src_menu + + # This is a scratch popup menu we use when we are not over a bp... + if {![winfo exists $popups(source)]} { + menu $popups(source) -tearoff 0 + } + + if {![winfo exists $popups(break_rgn)]} { + # breakpoint popup menu + # don't enable hardware or conditional breakpoints until they are tested + menu $popups(break_rgn) -tearoff 0 + + set bp_fg [pref get gdb/src/bp_fg] + set tp_fg [pref get gdb/src/trace_fg] + + if {[pref get gdb/control_target]} { + + addPopup break_rgn "Continue to Here" "$this continue_to_here" \ + [pref get gdb/src/PC_TAG] 0 0 + $popups(break_rgn) add separator + + addPopup break_rgn "Set Breakpoint" "$this set_bp_at_line" $bp_fg + + lappend popups(break_rgn-browse) 1 + lappend popups(break_rgn-control) 1 + + addPopup break_rgn "Set Temporary Breakpoint" "$this set_bp_at_line T" \ + [pref get gdb/src/temp_bp_fg] + + addPopup break_rgn "Set Breakpoint on Thread(s)..." \ + "$this ask_thread_bp" [pref get gdb/src/thread_fg] 0 0 + } + + if {$Tracing} { + $popups(break_rgn) add separator + addPopup break_rgn "Set Tracepoint" "$this set_tp_at_line" $tp_fg + } + + } + + if {![winfo exists $popups(bp)]} { + # this popup is used when the line contains a set breakpoint + menu $popups(bp) -tearoff 0 + + if {!$Browsing && [pref get gdb/control_target]} { + addPopup bp "Continue to Here" "$this continue_to_here" green 0 0 + $popups(bp) add separator + } + + addPopup bp "Delete Breakpoint" "$this remove_bp_at_line" $bp_fg + + # Currently you cannot set a tracepoint and a breakpoint at the same line... + # + # if {$Tracing} { + # addPopup bp "Set Tracepoint" "$this set_tp_at_line" $tp_fg + # } + } + + if {![winfo exists $popups(tp)]} { + # This is the popup to use when the line contains a set tracepoint + + menu $popups(tp) -tearoff 0 + + if {[pref get gdb/control_target]} { + + addPopup tp "Continue to Here" "$this continue_to_here" green 0 0 + # $popups(tp) add separator + + # Currently you cannot set a tracepoint and a breakpoint at the same line... + # + # addPopup tp "Set Breakpoint" "$this set_bp_at_line" $bp_fg + + # addPopup tp "Set Temporary Breakpoint" "$this set_bp_at_line T" \ + # [pref get gdb/src/temp_bp_fg] + + # addPopup tp "Set Breakpoint on Thread(s)..." \ + # "$this ask_thread_bp" \ + # [pref get gdb/src/thread_fg] 0 0 + } + + if {$Tracing} { + $popups(tp) add separator + addPopup tp "Modify Tracepoint" "$this set_tp_at_line" $tp_fg + addPopup tp "Delete Tracepoint" "$this remove_tp_at_line" $tp_fg + } + } + + # This is not currently used, since you can't set a bp & a tp on the same line. + # N.B. however, we don't exclude this on the command line, but... + + if {![winfo exists $popups(bp_and_tp)]} { + + # this popup is used when the line contains a set breakpoint & tracepoint + menu $popups(bp_and_tp) -tearoff 0 + + if {!$Browsing && [pref get gdb/control_target]} { + addPopup bp_and_tp "Continue to Here" "$this continue_to_here" \ + green 0 0 + $popups(bp_and_tp) add separator + } + + addPopup bp_and_tp "Delete Breakpoint" "$this remove_bp_at_line" $bp_fg + if {$Tracing} { + addPopup bp_and_tp "Modify Tracepoint" "$this set_tp_at_line" $tp_fg + addPopup bp_and_tp "Delete Tracepoint" \ + "$this remove_tp_at_line" $tp_fg + } + } + + if {![winfo exists $popups(tp_browse)]} { + + # this popup is on a tracepoint when browsing. + + menu $popups(tp_browse) -tearoff 0 + addPopup tp_browse "Next hit Here" "$this next_hit_at_line" \ + green + } + +} + +# ------------------------------------------------------------------ +# METHOD: build_win - build the main source paned window +# ------------------------------------------------------------------ +body SrcTextWin::build_win {} { + cyg::panedwindow $itk_interior.p -background white + + set _tpane pane$filenum + incr filenum + + $itk_interior.p add $_tpane + set pane1 [$itk_interior.p childsite $_tpane] + set Stwc(gdbtk_scratch_widget:pane) $_tpane + set Stwc(gdbtk_scratch_widget:dirty) 0 + + set twinp [iwidgets::scrolledtext $pane1.st -textbackground white \ + -hscrollmode dynamic -vscrollmode dynamic] + set twin [$twinp component text] + pack $twinp -fill both -expand yes + pack $itk_interior.p -fill both -expand yes + config_win $twin +} + +# ------------------------------------------------------------------ +# METHOD: SetRunningState - set state based on if GDB is running or not. +# This disables the popup menus when GDB is not running yet. +# ------------------------------------------------------------------ +body SrcTextWin::SetRunningState {state} { +# debug "$state" + foreach elem $popups(run_disabled) { + $popups([lindex $elem 0]) entryconfigure [lindex $elem 1] -state $state + } +} + +# ------------------------------------------------------------------ +# METHOD: enable - enable or disable bindings and change cursor +# ------------------------------------------------------------------ +body SrcTextWin::enable {on} { + if {$on} { + set Running 0 + set glyph "" + set bnd "" + set status normal + } else { + set Running 1 + set glyph watch + set bnd "break" + set status disabled + } + + bind $twin <B1-Motion> $bnd + bind $twin <Double-1> $bnd + bind $twin <Triple-1> $bnd + enable_disable_src_tags $twin $status + if {$bwin != ""} { + bind $bwin <B1-Motion> $bnd + bind $bwin <Double-1> $bnd + bind $bwin <Triple-1> $bnd + enable_disable_src_tags $bwin $status + } + + $twin configure -cursor $glyph + if {$bwin != ""} { + $bwin configure -cursor $glyph + } +} + +# ------------------------------------------------------------------ +# PROC: makeBreakDot - make the break dot for the screen +# ------------------------------------------------------------------ +body SrcTextWin::makeBreakDot {size colorList {image {}}} { + if {$size > 32} { + set size 32 + } elseif {$size < 1} { + set size 1 + } + + if {$image == ""} { + set image [image create photo -width $size -height $size] + } else { + $image blank + $image configure -width $size -height $size + } + + if {[llength $colorList] == 1} { + set x1 1 + set x2 [expr {1 + $size}] + set y1 1 + set y2 $x2 + $image put $colorList -to 1 1 $x2 $y2 + } else { + set x1 1 + set x3 [expr {1 + $size}] + set x2 [expr int((1 + $size)/2)] + set y1 1 + set y2 $x3 + $image put [lindex $colorList 0] -to 1 1 $x2 $y2 + $image put [lindex $colorList 1] -to [expr $x2 + 1] 1 $x3 $y2 + } + + return $image +} + +# ------------------------------------------------------------------ +# METHOD: setTabs - set the tabs for the assembly/src windows +# ------------------------------------------------------------------ +body SrcTextWin::setTabs {win {asm ""}} { + set fsize [font measure src-font "W"] + set tsize [pref get gdb/src/tab_size] + set rest "" + + if {$asm != ""} { + set first [expr {$fsize * 12}] + set second [expr {$fsize * 13}] + set third [expr {$fsize * 34}] + for {set i 1} {$i < 8} {incr i} { + lappend rest [expr {(34 + ($i * $tsize)) * $fsize}] left + } + set tablist [concat [list $first right $second left $third left] $rest] + } else { + # SOURCE window + # The first tab right-justifies the line numbers and the second + # tab is the left margin for the start on the source code. The remaining + # tabs should be regularly spaced depending on prefs. + if {$Linenums} { + set first [expr {$fsize * 6}] ;# "- " plus 4 digit line number + set second [expr {$fsize * 7}] ;# plus a space after the number + for {set i 1} {$i < 8} {incr i} { + lappend rest [expr {(7 + ($i * $tsize)) * $fsize}] left + } + set tablist [concat [list $first right $second left] $rest] + } else { + set first [expr {$fsize * 2}] + for {set i 1} {$i < 8} {incr i} { + lappend rest [expr {(2 + ($i * $tsize)) * $fsize}] left + } + set tablist [concat [list $first left] $rest] + } + } + $win configure -tabs $tablist +} + +body SrcTextWin::enable_disable_src_tags {win how} { + + switch $how { + normal { + set cur1 dot + set cur2 xterm + } + disabled { + set cur1 watch + set cur2 $cur1 + } + browse { + set cur1 dot + set cur2 xterm + } + } + + if {[string compare $how browse] == 0} { + + $win tag bind break_rgn_tag <Enter> { } + $win tag bind break_rgn_tag <Leave> { } + + foreach type $bp_types { + $win tag bind ${type}_tag <Enter> { } + $win tag bind ${type}_tag <Motion> { } + $win tag bind ${type}_tag <Leave> { } + } + + } else { + + $win tag bind break_rgn_tag <Enter> "$win config -cursor $cur1" + $win tag bind break_rgn_tag <Leave> "$win config -cursor $cur2" + + foreach type $bp_types { + $win tag bind ${type}_tag <Enter> "$win config -cursor $cur1" + $win tag bind ${type}_tag <Motion> "$this motion bp %W %x %y" + $win tag bind ${type}_tag <Leave> \ + "$this cancelMotion;$win config -cursor $cur2" + } + } + + $win tag bind tp_tag <Enter> "$win config -cursor $cur1" + $win tag bind tp_tag <Motion> "$this motion bp %W %x %y" + $win tag bind tp_tag <Leave> "$this cancelMotion;$win config -cursor $cur2" +} + +# ------------------------------------------------------------------ +# METHOD: config_win - configure the source or assembly text window +# ------------------------------------------------------------------ +body SrcTextWin::config_win {win {asm ""}} { +# debug "$win $asm Tracing=$Tracing Browsing=$Browsing" + + $win config -borderwidth 2 -insertwidth 0 -wrap none -bg white + + # font + set font [pref get gdb/src/font] + $win configure -font $font + + setTabs $win $asm + + # set up some tags. should probably be done differently + # !! change bg? + + $win tag configure break_rgn_tag -foreground [pref get gdb/src/break_fg] + foreach type $bp_types { + $win tag configure ${type}_tag -foreground [pref get gdb/src/break_fg] + } + $win tag configure tp_tag -foreground [pref get gdb/src/break_fg] + $win tag configure source_tag2 -foreground [pref get gdb/src/source2_fg] + $win tag configure PC_TAG -background [pref get gdb/src/PC_TAG] + $win tag configure STACK_TAG -background [pref get gdb/src/STACK_TAG] + $win tag configure BROWSE_TAG -background [pref get gdb/src/BROWSE_TAG] + + # search tag used to highlight searches + foreach option [$win tag configure sel] { + set op [lindex $option 0] + set val [lindex $option 4] + eval $win tag configure search $op $val + } + + # bind mouse button 3 to the popup men + $win tag bind source_tag <Button-3> "$this do_source_popup %X %Y %x %y" + $win tag bind source_tag2 <Button-3> "$this do_source_popup %X %Y %x %y" + + # bind mouse button 3 to the popup menus + if {!$Browsing} { + + $win tag bind break_rgn_tag <Button-3> \ + "$this do_tag_popup break_rgn %X %Y %y; break" + foreach type $bp_types { + $win tag bind ${type}_tag <Button-3> "$this do_tag_popup bp %X %Y %y; break" + } + $win tag bind tp_tag <Button-3> "$this do_tag_popup tp %X %Y %y; break" + $win tag bind bp_and_tp_tag <Button-3> "$this do_tag_popup bp_and_tp %X %Y %y; break" + } else { + $win tag bind tp_tag <Button-3> "$this do_tag_popup tp_browse %X %Y %y; break" + $win tag bind break_rgn_tag <Button-3> { } + foreach type $bp_types { + $win tag bind ${type}_tag <Button-3> { } + } + $win tag bind bp_and_tp_tag <Button-3> "$this do_tag_popup tp_browse %X %Y %y; break" + + } + + # Disable printing and cut and paste keys; makes the window readonly + # We do this so we don't have to enable and disable the + # text widget everytime we want to modify it. + + bind $win <Key> {if {"%A" != "{}"} {break}} + bind $win <Delete> break + bind $win <ButtonRelease-2> {break} + + # GDB key bindings + # We need to explicitly ignore keys with the Alt modifier, since + # otherwise they will interfere with selecting menus on Windows. + + if {!$Browsing && [pref get gdb/control_target]} { + bind_plain_key $win c "$this do_key continue; break" + bind_plain_key $win r "$this do_key run; break" + bind_plain_key $win f "$this do_key finish; break" + } else { + bind_plain_key $win n "$this do_key tfind_next; break" + bind_plain_key $win p "$this do_key tfind_prev; break" + bind_plain_key $win f "$this do_key tfind_start; break" + bind_plain_key $win l "$this do_key tfind_line; break" + bind_plain_key $win h "$this do_key tfind_tp; break" + } + bind_plain_key $win u "$this do_key up; break" + bind_plain_key $win d "$this do_key down; break" + bind_plain_key $win x "$this do_key quit; break" + + if {!$Browsing && [pref get gdb/control_target]} { + if {$asm != ""} { + bind_plain_key $win s "$this do_key stepi; break" + bind_plain_key $win n "$this do_key nexti; break" + } else { + bind_plain_key $win s "$this do_key step; break" + bind_plain_key $win n "$this do_key next; break" + } + } + + bind_plain_key $win Control-h "$this do_key thread_list; break" + bind_plain_key $win Control-f "$this do_key browser; break" + bind_plain_key $win Control-d "$this do_key download; break" + bind_plain_key $win Control-p "$this do_key print" + bind_plain_key $win Control-u "$this do_key debug; break" + bind_plain_key $win Control-o [list $this do_key open] + + if {!$Browsing && [pref get gdb/control_target]} { + # Ctrl+F5 is another accelerator for Run + bind_plain_key $win Control-F5 "$this do_key run" + } + + bind_plain_key $win Control-F11 "$this do_key debug" + bind_plain_key $win Alt-v "$win yview scroll -1 pages" + bind_plain_key $win Control-v [format { + %s yview scroll 1 pages + break + } $win] + + # bind mouse button 1 to the breakpoint method or tracepoint, + # depending on the settings of the B1_behavior setting. We don't + # have to bind to bp_and_tp because that will fall through to either + # the tp or the bp tag. We have to put in the break so that we don't + # both remove & reinsert a BP when we have both a tp & a bp on the same line. + # If we are browsing, then disable Button-1 + + if {!$Browsing} { + if {[pref get gdb/B1_behavior]} { + $win tag bind break_rgn_tag <Button-1> "$this set_bp_at_line N $win %y; break" + foreach type $bp_types { + $win tag bind ${type}_tag <Button-1> "$this remove_bp_at_line $win %y; break" + } + $win tag bind tp_tag <Button-1> "$this set_bp_at_line N $win %y; break" + } else { + $win tag bind break_rgn_tag <Button-1> "$this set_tp_at_line $win %y; break" + foreach type $bp_types { + $win tag bind ${type}_tag <Button-1> "$this set_tp_at_line $win %y; break" + } + $win tag bind tp_tag <Button-1> "$this set_tp_at_line $win %y; break" + } + } else { + $win tag bind break_rgn_tag <Button-1> { } + foreach type $bp_types { + $win tag bind ${type}_tag <Button-1> { } + } + $win tag bind tp_tag <Button-1> { } + } + + + # avoid special handling of double and triple clicks in break area + bind $win <Double-1> [format { + if {[lsearch [%s tag names @%%x,%%y] break_rgn_tag] >= 0} { + break + } + } $win $win] + bind $win <Triple-1> [format { + if {[lsearch [%s tag names @%%x,%%y] break_rgn_tag] >= 0} { + break + } + } $win $win] + + # bind window shortcuts + bind_plain_key $win Control-s "$this do_key stack" + bind_plain_key $win Control-r "$this do_key registers" + bind_plain_key $win Control-m "$this do_key memory" + bind_plain_key $win Control-w "$this do_key watch" + bind_plain_key $win Control-l "$this do_key locals" + bind_plain_key $win Control-k "$this do_key kod" + if { !$Tracing } { + bind_plain_key $win Control-b "$this do_key breakpoints" + } else { + bind_plain_key $win Control-t "$this do_key tracepoints" + bind_plain_key $win Control-u "$this do_key tdump" + } + bind_plain_key $win Control-n "$this do_key console" + + if {$Browsing} { + enable_disable_src_tags $win browse + } else { + enable_disable_src_tags $win normal + } + + if {$UseVariableBalloons} { + $win tag bind source_tag <Motion> "$this motion var %W %x %y" + $win tag bind source_tag <Leave> "$this cancelMotion" + } + + # Up/Down arrow key bindings + bind_plain_key $win Up [list %W yview scroll -1 units] + bind_plain_key $win Down [list %W yview scroll +1 units] +} + +# ------------------------------------------------------------------ +# METHOD: addPopup - adds a popup to one of the source popup menus +# ------------------------------------------------------------------ +body SrcTextWin::addPopup {menu label command {abg {}} {browse 1} {run 1}} { + + if {$abg == ""} { + $popups($menu) add command -label $label -command $command + } else { + $popups($menu) add command -label $label -command $command \ + -activebackground $abg + } + + set index [$popups($menu) index last] + if {!$run} { + lappend popups(run_disabled) [list $menu $index] + } + if {!$browse} { + lappend popups(browse_disabled) [list $menu $index] + } + +} +# ------------------------------------------------------------------ +# METHOD: handle_set_hook - Handle changes in the gdb variables +# changed through the "set" gdb command. +# ------------------------------------------------------------------ +body SrcTextWin::handle_set_hook {var val} { + debug "Set hook got called with $var $val" + switch $var { + disassembly-flavor { + disassembly_changed + } + } +} + +# ------------------------------------------------------------------ +# METHOD: disassembly_changed - The disassembly flavor has changed, +# mark all the cached assembly windows dirty, and force the +# visible window to be redisplayed. +# ------------------------------------------------------------------ +body SrcTextWin::disassembly_changed {} { + foreach name [array names Stwc *:pane] { + debug "Looking at $name" + set vals [split $name ,] + if {([string compare [lindex $vals 1] "A"] == 0) + || ([string compare [lindex $vals 1] "M"] == 0)} { + debug "Setting $name to dirty" + set Stwc([lindex $vals 0]:dirty) 1 + } + } + + if {[string compare $current(mode) "SOURCE"] != 0} { + location $current(tag) $current(filename) $current(funcname) $current(line) \ + $current(addr) $pc(addr) $current(lib) + } +} + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body SrcTextWin::reconfig {} { +# debug + + # Make sure we redo the break images when we reconfigure + set size [font measure src-font "W"] + makeBreakDot $size [pref get gdb/src/bp_fg] $break_images(bp) + makeBreakDot $size [pref get gdb/src/temp_bp_fg] $break_images(temp_bp) + makeBreakDot $size [pref get gdb/src/disabled_fg] $break_images(disabled_bp) + makeBreakDot $size [pref get gdb/src/trace_fg] $break_images(tp) + makeBreakDot $size \ + [list [pref get gdb/src/trace_fg] [pref get gdb/src/bp_fg]] \ + $break_images(bp_and_tp) + makeBreakDot $size [pref get gdb/src/thread_fg] $break_images(thread_bp) + + # Tags + $twin tag configure PC_TAG -background [pref get gdb/src/PC_TAG] + $twin tag configure STACK_TAG -background [pref get gdb/src/STACK_TAG] + $twin tag configure BROWSE_TAG -background [pref get gdb/src/BROWSE_TAG] + switch $current(mode) { + SOURCE { + setTabs $twin + } + SRC+ASM { + setTabs $twin + setTabs $bwin A + } + default { + setTabs $twin A + } + } + + # Variable Balloons + if {$ignore_var_balloons} { + set balloons 0 + } else { + set balloons [pref get gdb/src/variableBalloons] + } + if {$UseVariableBalloons != $balloons} { + set UseVariableBalloons $balloons + if {$UseVariableBalloons} { + $twin tag bind source_tag <Motion> "$this motion var %W %x %y" + $twin tag bind source_tag <Leave> "$this cancelMotion" + add_hook gdb_idle_hook [list $this updateBalloon] + } else { + cancelMotion + $twin tag bind source_tag <Motion> {} + $twin tag bind source_tag <Leave> {} + $twin tag remove _show_variable 1.0 end + remove_hook gdb_idle_hook [list $this updateBalloon] + } + } + + # Tracing Hooks + catch {remove_hook control_mode_hook "$this set_control_mode"} + catch {remove_hook gdb_trace_find_hook "$this trace_find_hook"} + if {$Tracing} { + add_hook control_mode_hook "$this set_control_mode" + add_hook gdb_trace_find_hook "$this trace_find_hook" + } + + # Popup colors + + # need to rewrite because of the new addPopup function + # if {$Tracing} { + # $twin.bmenu entryconfigure 0 -activebackground [pref get gdb/src/trace_fg] + # } else { + # $twin.bmenu entryconfigure 0 -activebackground [pref get gdb/src/PC_TAG] + # $twin.bmenu entryconfigure 1 -activebackground [pref get gdb/src/bp_fg] + # $twin.bmenu entryconfigure 2 -activebackground \ + # [pref get gdb/src/temp_bp_fg] + # $twin.bmenu entryconfigure 3 -activebackground \ + # [pref get gdb/src/thread_fg] + # } +} + +# ------------------------------------------------------------------ +# METHOD: updateBalloon - we have gone idle, update the balloon +# ------------------------------------------------------------------ +body SrcTextWin::updateBalloon {} { + + set err [catch {$_balloon_var update} changed] + catch {$_balloon_var name} var + + if {!$err} { + if {$changed != ""} { + # The variable's value has changed, so update the + # balloon with its new value + balloon register $twin "$var=[balloon_value $_balloon_var]" _show_variable + } + } + } + +body SrcTextWin::balloon_value {variable} { + + catch {$variable value} value + set value [string trim $value \ \r\t\n] + + # Insert the variable's type for things like ptrs, etc. + catch {$variable type} type + if {$value == "{...}"} { + set val "$type $value" + } elseif {[regexp -- {0x([0-9a-fA-F]+) <[a-zA-Z_].*} $value str]} { + set val $str + } elseif {[string first * $type] != -1} { + set val "($type) $value" + } elseif {[string first \[ $type] != -1} { + set val "$type" + } else { + set val "$value" + } + + return $val +} + +# ------------------------------------------------------------------ +# METHOD: ClearTags - clear all tags +# ------------------------------------------------------------------ +body SrcTextWin::ClearTags {} { + foreach tag {PC_TAG BROWSE_TAG STACK_TAG} { + catch { + $twin tag remove $tag $current(line).2 $current(line).end + $twin tag remove $tag $pc(line).2 $pc(line).end + $twin tag remove $tag $current(asm_line).2 $current(asm_line).end + if {$bwin != ""} { + $bwin tag remove $tag $current(asm_line).2 $current(asm_line).end + } + } + } +} + +# ------------------------------------------------------------------ +# METHOD: _mtime_changed - check if the modtime for a file +# has changed. +# ------------------------------------------------------------------ +body SrcTextWin::_mtime_changed {filename} { + set f [gdb_find_file $filename] + + if {$f == ""} { + set r 1 + } else { + set mtime [file mtime $f] + if {![info exists Stwc($filename:mtime)]} { + debug "no mtime. resetting to zero" + set Stwc($filename:mtime) 0 + } + # debug "Stwc($filename:mtime)=$Stwc($filename:mtime); mtime=$mtime" + + if {$mtime == $Stwc($filename:mtime)} { + set r 0 + } else { + set r 1 + set Stwc($filename:mtime) $mtime + set Stwc($filename:dirty) 1 + } + } + + return $r +} + +# ------------------------------------------------------------------ +# METHOD: FillSource - fill a window with source +# ------------------------------------------------------------------ +body SrcTextWin::FillSource {w tagname filename funcname line addr pc_addr lib} { + global gdb_running + upvar ${w}win win + +# debug "$gdb_running $tagname line=$line pc(line)=$pc(line)" +# debug "current(filename)=$current(filename) filename=$filename" + + if {$filename != ""} { + # load new file if necessary + set mtime [_mtime_changed $filename] + if {[string compare $filename $current(filename)] != 0 \ + || $mode_changed || $mtime} { + if {![LoadFile $w $filename $lib $mtime]} { + # failed to find source file + dbug W "Changing to ASSEMBLY" + set current(line) $line + set current(tag) $tagname + set current(addr) $addr + set current(funcname) $funcname + set current(filename) $filename + set current(lib) $lib + set oldmode SOURCE + $parent mode "" ASSEMBLY + return + } + if {$current(mode) != "SRC+ASM"} { + # reset this flag in FillAssembly for SRC+ASM mode + set mode_changed 0 + } + } + +# debug "cf=$current(filename) pc=$pc(filename) filename=$filename" + if {$current(filename) != ""} { + if {$gdb_running && $pc(filename) == $filename} { + # set the PC tag in this file + $win tag add PC_TAG $pc(line).2 $pc(line).end + } + if {$tagname != "PC_TAG"} { + if {$gdb_running && ($pc(filename) == $filename) \ + && ($pc(line) == $line)} { + # if the tag is on the same line as the PC, set a PC tag + $win tag add PC_TAG $line.2 $line.end + } else { + $win tag add $tagname $line.2 $line.end + } + } + if {$pc(filename) == $filename && $line == 0} { + # no line specified, so show line with PC + display_line $win $pc(line) + } else { + display_line $win $line + } + } + return + } + # no source; switch to assembly +# debug "no source file; switch to assembly" + set current(line) $line + set current(tag) $tagname + set current(addr) $addr + set current(funcname) $funcname + set current(filename) $filename + set current(lib) $lib + set oldmode $current(mode) + $parent mode "" ASSEMBLY +} + +# ------------------------------------------------------------------ +# METHOD: FillAssembly - fill a window with disassembled code +# ------------------------------------------------------------------ +body SrcTextWin::FillAssembly {w tagname filename funcname line addr pc_addr lib} { + global gdb_running + upvar ${w}win win + upvar _${w}pane pane +# debug "$win $tagname $filename $funcname $line $addr $pc_addr" +# debug "mode_changed=$mode_changed" +# debug "funcname=$funcname" +# debug "current(funcname)=$current(funcname)" + if {$funcname == ""} { + set oldpane $pane + set pane $Stwc(gdbtk_scratch_widget:pane) + set win [[$itk_interior.p childsite $pane].st component text] + $win delete 0.0 end + $win insert 0.0 "Select function name to disassemble" + if {$oldpane != "" && $oldpane != $pane} { + $itk_interior.p replace $oldpane $pane + } else { + $itk_interior.p show $pane + } + return + } elseif {$funcname != $current(funcname) || $mode_changed + || ([info exists Stwc($addr:dirty)] && $Stwc($addr:dirty))} { + set mode_changed 0 + set oldpane $pane + if {[LoadFromCache $w $addr A $lib]} { + #debug [format "Disassembling at %x" $addr] + #debug "cf=$current(filename) name=$filename" + if {[catch {gdb_load_disassembly $win nosource \ + [scope _map] $Cname $addr} mess]} { + # print some intelligent error message? + dbug E "Disassemble failed: $mess" + UnLoadFromCache $w $oldpane $addr A $lib + set pane $Stwc(gdbtk_scratch_widget:pane) + set win [[$itk_interior.p childsite $pane].st component text] + $win delete 0.0 end + $win insert 0.0 "Unable to Read Instructions at $addr" + if {$oldpane != "" && $oldpane != $pane} { + $itk_interior.p replace $oldpane $pane + } else { + $itk_interior.p show $pane + } + } else { + foreach {asm_lo_addr asm_hi_addr} $mess {break} + debug "Got low address: $asm_lo_addr and high: $asm_hi_addr" + } + } + set current(filename) $filename + set do_display_breaks 1 + } + + # highlight proper line number + if {[info exists _map($Cname,pc=$addr)]} { + # if current file has PC, highlight that too + if {$gdb_running && $tagname != "PC_TAG" && $pc(filename) == $filename + && $pc(func) == $funcname} { + set pc(asm_line) $_map($Cname,pc=$pc_addr) + $win tag add PC_TAG $pc(asm_line).2 $pc(asm_line).end + } + set current(asm_line) $_map($Cname,pc=$addr) + # don't set browse tag if it is at PC + if {$pc_addr != $addr || $tagname == "PC_TAG"} { + # HACK. In STACK mode we usually want the previous instruction + # but not when we are browsing a trace experiment. + if {[string compare $tagname "STACK_TAG"] == 0 && !$Browsing} { + incr current(asm_line) -1 + } + $win tag add $tagname $current(asm_line).2 $current(asm_line).end + } + } + display_line $win $current(asm_line) +} + + +# ------------------------------------------------------------------ +# METHOD: FillMixed - fill a window with mixed source and assembly +# ------------------------------------------------------------------ +body SrcTextWin::FillMixed {w tagname filename funcname line addr pc_addr lib} { + global gdb_running + upvar ${w}win win + upvar _${w}pane pane +# debug "$win $tagname $filename $funcname $line $addr $pc_addr" + + set asm_lo_addr "" + + if {$funcname == ""} { + set oldpane $pane + set pane $Stwc(gdbtk_scratch_widget:pane) + set win [[$itk_interior.p childsite $pane].st component text] + $win delete 0.0 end + $win insert 0.0 "Select function name to disassemble" + if {$oldpane != ""} { + $itk_interior.p replace $oldpane $pane + } else { + $itk_interior.p show $pane + } + } elseif {$funcname != $current(funcname) || $mode_changed + || ([info exists Stwc($funcname:dirty)] && $Stwc($funcname:dirty))} { + set mode_changed 0 + set oldpane $pane + if {[LoadFromCache $w $funcname M $lib]} { + # debug [format "Disassembling at %x" $addr] + if {[catch {gdb_load_disassembly $win source \ + [scope _map] $Cname $addr} mess] } { + # print some intelligent error message + dbug W "Disassemble Failed: $mess" + UnLoadFromCache $w $oldpane $funcname M $lib + set current(line) $line + set current(tag) $tagname + set current(addr) $addr + set current(funcname) $funcname + set current(filename) $filename + set current(lib) $lib + set oldmode MIXED + $parent mode "" ASSEMBLY + return + } else { + foreach {asm_lo_addr asm_hi_addr} $mess {break} + debug "Got low address: $asm_lo_addr and high: $asm_hi_addr" + } + } + set current(filename) $filename + # now set the breakpoints + set do_display_breaks 1 + } + # highlight proper line number + if {[info exists _map($Cname,pc=$addr)]} { + # if current file has PC, highlight that too + if {$gdb_running && $tagname != "PC_TAG" && $pc(filename) == $filename + && $pc(func) == $funcname} { + set pc(asm_line) $_map($Cname,pc=$pc_addr) + $win tag add PC_TAG $pc(asm_line).2 $pc(asm_line).end + } + set current(asm_line) $_map($Cname,pc=$addr) +# debug "current(asm_line) = $current(asm_line)" + if {$pc_addr != $addr || $tagname == "PC_TAG"} { + # HACK. In STACK mode we usually want the previous instruction + if {$tagname == "STACK_TAG"} { + incr current(asm_line) -1 + } + $win tag add $tagname $current(asm_line).2 $current(asm_line).end + } + } + display_line $win $current(asm_line) +} + +# ------------------------------------------------------------------ +# METHOD: location - display a location in a file +# ------------------------------------------------------------------ +body SrcTextWin::location {tagname filename funcname line addr pc_addr lib} { +# debug "$tagname $filename $line $addr $pc_addr, mode=$current(mode) oldmode=$oldmode cf=$current(filename) lib=$lib" + + ClearTags + + # It seems odd to do this as a string compare, but on the Alpha, + # where ints are 32 bit but addresses are 64, a numerical compare + # will overflow Tcl's ints. + + if {$tagname == "PC_TAG" && [string compare $addr $pc_addr] == 0} { + set pc(filename) $filename + set pc(line) $line + set pc(addr) $addr + set pc(func) $funcname + set pc(lib) $lib + } + + if {$oldmode != "" \ + && [string compare $filename $current(filename)] != 0} { + if {[gdb_find_file $filename] != ""} { + set tmp $oldmode + set oldmode "" + $parent mode "" $tmp 0 + } + } + + switch $current(mode) { + SOURCE { + FillSource t $tagname $filename $funcname $line $addr $pc_addr $lib + } + ASSEMBLY { + FillAssembly t $tagname $filename $funcname $line $addr $pc_addr $lib + } + MIXED { + FillMixed t $tagname $filename $funcname $line $addr $pc_addr $lib + } + SRC+ASM { + FillSource t $tagname $filename $funcname $line $addr $pc_addr $lib + # This may seem redundant, but it is NOT. FillSource can change + # the mode from SOURCE to ASSEMBLY if sources were not found. If + # this happens, then MIXED mode is pointless, so forget the bottom + # pane. + if {$current(mode) == "SRC+ASM"} { + FillAssembly b $tagname $filename $funcname $line $addr $pc_addr $lib + } + } + } + set current(line) $line + set current(tag) $tagname + set current(addr) $addr + set current(funcname) $funcname + set current(filename) $filename + set current(lib) $lib + if {$do_display_breaks} { + display_breaks + set do_display_breaks 0 + } +} + +# ------------------------------------------------------------------ +# METHOD: LoadFile - loads in a new source file +# ------------------------------------------------------------------ +body SrcTextWin::LoadFile {w name lib mtime_changed} { +# debug "$name $current(filename) $current(mode)" + upvar ${w}win win + upvar _${w}pane pane + + set oldpane $pane + if {[LoadFromCache $w $name "" $lib] || $mtime_changed} { + $win delete 0.0 end +# debug "READING $name" + if {[catch {gdb_loadfile $win $name $Linenums} msg]} { + dbug W "Error opening $name: $msg" + #if {$msg != ""} { + # tk_messageBox -icon error -title "GDB" -type ok \ + # -modal task -message $msg + #} + UnLoadFromCache $w $oldpane $name "" $lib + return 0 + } + } + set current(filename) $name + # Display all breaks/traces + set do_display_breaks 1 + return 1 +} + +# ------------------------------------------------------------------ +# METHOD: display_line - make sure a line is displayed and near the center +# ------------------------------------------------------------------ + +body SrcTextWin::display_line { win line } { + ::update idletasks + # keep line near center of display + set pixHeight [winfo height $win] + set topLine [lindex [split [$win index @0,0] .] 0] + set botLine [lindex [split [$win index @0,${pixHeight}] .] 0] + set margin [expr {int(0.2*($botLine - $topLine))}] + if {$line < [expr {$topLine + $margin}]} { + set num [expr {($topLine - $botLine) / 2}] + } elseif {$line > [expr {$botLine - $margin}]} { + set num [expr {($botLine - $topLine) / 2}] + } else { + set num 0 + } + $win yview scroll $num units + $win see $line.0 +} + +# ------------------------------------------------------------------ +# METHOD: display_breaks - insert all breakpoints and tracepoints +# uses current(filename) in SOURCE mode +# ------------------------------------------------------------------ + +body SrcTextWin::display_breaks {} { +# debug + + # clear any previous breakpoints + foreach type "$bp_types tp" { + foreach {start stop} [$twin tag ranges ${type}_tag] { + scan $start "%d." linenum + removeBreakTag $twin $linenum ${type}_tag + } + } + + # now do second pane if it exists + if {[info exists bwin]} { + foreach type "$bp_types tp" { + foreach {start stop} [$twin tag ranges ${type}_tag] { + scan $start "%d." linenum + removeBreakTag $twin $linenum ${type}_tag + } + } + } + + # Display any existing breakpoints. + foreach bpnum [gdb_get_breakpoint_list] { + set info [gdb_get_breakpoint_info $bpnum] + set addr [lindex $info 3] + set line [lindex $info 2] + set file [lindex $info 0] + set type [lindex $info 6] + set enabled [lindex $info 5] + bp create $bpnum $addr $line $file $type $enabled + } + # Display any existing tracepoints. + foreach bpnum [gdb_get_tracepoint_list] { + set info [gdb_get_tracepoint_info $bpnum] + set addr [lindex $info 3] + set line [lindex $info 2] + set file [lindex $info 0] + bp create $bpnum $addr $line $file tracepoint + } +} + +# ------------------------------------------------------------------ +# METHOD: insertBreakTag - insert the right amount of tag chars +# into the text window WIN, at line linenum. +# ------------------------------------------------------------------ +body SrcTextWin::insertBreakTag {win linenum tag} { +# debug "$win $linenum $tag" + + # Get the tags at the current line. + + # If there is a "break_rgn_tag", then there are currently no other + # break/trace points at this line. So replace the break_rgn_tag + # with this tag. Otherwise, add the new tag, and then the joint + # tag. We will query the length of the previous tag, so we don't have + # to hard code it here. + + set tag_list [$win tag names $linenum.0] + set img_name [string range $tag 0 [expr [string length $tag] - 5]] + + if {[lsearch $tag_list break_rgn_tag] != -1} { + set stop [lindex [$win tag nextrange break_rgn_tag \ + $linenum.0 "$linenum.0 lineend"] 1] + $win tag remove break_rgn_tag $linenum.0 "$linenum.0 lineend" + $win delete $linenum.0 + + # Strip the "_tag" off the end of the tag to get the image name. + $win image create $linenum.0 -image $break_images($img_name) + $win tag add $tag $linenum.0 $stop + } else { + + set other_tag [lindex $tag_list \ + [lsearch -glob $tag_list {*[bt]p_tag}]] + if {$other_tag == ""} { + set stop 4 + } else { + set stop [lindex [$win tag nextrange $other_tag \ + $linenum.0 "$linenum.0 lineend"] 1] + } + + $win tag add $tag $linenum.0 $stop + $win image configure $linenum.0 -image $break_images($img_name) + + } +} + +# ------------------------------------------------------------------ +# METHOD: removeBreakTag - remove a break tag (breakpoint or tracepoint) +# from the given line. If this is the last break tag on the +# line reinstall the break_rgn_tag +# ------------------------------------------------------------------ +body SrcTextWin::removeBreakTag {win linenum tag } { +# debug "$win $linenum $tag" + + set tag_list [$win tag names $linenum.0] + + if {[set pos [lsearch -exact $tag_list $tag]] == -1} { + debug "Tried to remove non-existant tag $tag" + return + } else { + set tag_list [lreplace $tag_list $pos $pos] + } + + # Use the range of the removed tag for any insertions, so we don't + # have to hard code it here. + + set stop [lindex [$win tag nextrange $tag \ + $linenum.0 "$linenum.0 lineend"] 1] + + $win tag remove $tag $linenum.0 "$linenum.0 lineend" + + # Now check what other tags are on this line. If there are both bp & tp + # tags, also remove the joint tag, otherwise install the break_rgn_tag. + + switch -glob $tag { + *bp_tag { + set only_one_tag [expr [set next_tag_index \ + [lsearch -glob $tag_list tp_tag]] == -1] + } + tp_tag { + # Got to find out what kind of tag is here... + set only_one_tag [expr [set next_tag_index \ + [lsearch -glob $tag_list *bp_tag]] == -1] + } + } + + if {$only_one_tag} { + catch {$win image configure $linenum.0 -image {}} + $win delete $linenum.0 + $win insert $linenum.0 "-" + $win tag add break_rgn_tag $linenum.0 $stop + } else { + set other_tag [lindex $tag_list $next_tag_index] + set img_name [string range $other_tag 0 \ + [expr [string length $other_tag] - 5]] + $win image configure $linenum.0 -image $break_images($img_name) + $win tag remove bp_and_tp_tag $linenum.0 "$linenum.0 lineend" + } +} + +# ------------------------------------------------------------------ +# METHOD: bp - set and remove breakpoints +# +# if $addr is valid, the breakpoint will be set in the assembly or +# mixed window at that address. If $line and $file are valid, +# a breakpoint will be set in the source window if appropriate. +# ------------------------------------------------------------------ +body SrcTextWin::bp {action bpnum addr {linenum {}} {file {}} {type 0} {enabled 0} {thread -1}} { +# debug "$action addr=$addr line=$linenum file=$file type=$type current(filename)=$current(filename)" + + switch $current(mode) { + SOURCE { + if {[string compare $file $current(filename)] == 0 && $linenum != {}} { + do_bp $twin $action $linenum $type $bpnum $enabled $thread 0 + } + } + + SRC+ASM { + if {$addr != {} && [info exists _map($Cname,pc=$addr)]} { + do_bp $bwin $action $_map($Cname,pc=$addr) $type $bpnum \ + $enabled $thread 1 + } + if {[string compare $file $current(filename)] == 0 && $linenum != {}} { + do_bp $twin $action $linenum $type $bpnum $enabled $thread 0 + } + } + + ASSEMBLY { + if {$addr != {} &&[info exists _map($Cname,pc=$addr)]} { + do_bp $twin $action $_map($Cname,pc=$addr) $type $bpnum \ + $enabled $thread 1 + } + } + + MIXED { + if {$addr != {} && [info exists _map($Cname,pc=$addr)]} { + do_bp $twin $action $_map($Cname,pc=$addr) $type $bpnum \ + $enabled $thread 1 + } + } + } +} + +# ------------------------------------------------------------------ +# METHOD: do_bp - bp helper function +# ------------------------------------------------------------------ +body SrcTextWin::do_bp { win action linenum type bpnum enabled thread asm} { +# debug "$action line=$linenum type=$type bpnum=$bpnum enabled=$enabled thread=$thread" + + if {$dont_change_appearance} { + return + } + + if {!$asm && $action == "delete" && [string compare $type tracepoint] != 0} { + # make sure there are no more breakpoints on + # this line. + set bps [gdb_find_bp_at_line $current(filename) $linenum] + if {[llength $bps] > 0} { + foreach b $bps { + if {$b != $bpnum} { + # OK we found another BP on this line. + # So we really just want to modify whats + # displayed on the line instead of deleting it. + # Also, for lack of a better solution, we will + # just display an image corresponding to the + # first found BP. If you have a temporary and + # a perm BP on the same line, the image for the one + # with the lower bpnum will be displayed. + set inf [gdb_get_breakpoint_info $b] + set action "modify" + set type [lindex $inf 6] + set bpnum $b + break + } + } + } + } + + if {[string compare $type "tracepoint"] == 0} { + if {[string compare $action "delete"] != 0 + && [lindex [gdb_get_tracepoint_info $bpnum] 4] == 0} { + set type disabled_tracepoint + } + } else { + if {$enabled == "0" } { + set type disabled_bp + } elseif {$thread != "-1"} { + set type thread + } + } + + switch $type { + donttouch { + set tag_type bp_tag + } + delete { + set tag_type temp_bp_tag + } + disabled_bp { + set tag_type disabled_bp_tag + } + tracepoint { + set tag_type tp_tag + } + disabled_tracepoint { + set tag_type disabled_tp_tag + } + thread { + set tag_type thread_bp_tag + } + default { + dbug E "UNKNOWN BP TYPE $action $type" + $win insert $linenum.0 "X" bp_tag + set tag_type bp_tag + } + } + + if {[string compare $action "delete"] == 0} { + removeBreakTag $win $linenum $tag_type + } else { + if {[string compare $action "modify"] == 0} { + removeBreakTag $win $linenum $tag_type + } + insertBreakTag $win $linenum $tag_type + } +} + + +# ------------------------------------------------------------------ +# METHOD: hasBP - see if a line number has a breakpoint set +# ------------------------------------------------------------------ +body SrcTextWin::hasBP {win line} { + if {$win == ""} { + set win $popups(saved_win) + } + + if {[lsearch -glob [$win tag names $line.0] *bp_tag] >= 0} { + return 1 + } + return 0 +} + +# ------------------------------------------------------------------ +# METHOD: hasTP - see if a line number has a tracepoint set +# ------------------------------------------------------------------ +body SrcTextWin::hasTP {win line} { + if {$win == ""} { + set win $popups(saved_win) + } + + if {[lsearch -exact [$win tag names $line.0] tp_tag] == 1} { + return 1 + } + return 0 +} + +# ------------------------------------------------------------------ +# METHOD: report_current_location +# +# This function reports the "current" location in the source +# window, where current means what gdb_loc would return, if +# that point is actually visible in the window, or the middle +# of the current window, if that point is not visible. +# +# Return: +# The gdb_loc result for the location found +# ------------------------------------------------------------------ +body SrcTextWin::report_source_location {} { + + if {$current(filename) == ""} { + error "No source file in window" + } + + # Figure out if the return from gdb_loc is visible. + + set not_visible 1 + if {![catch {gdb_loc} loc_info]} { + set loc_long_name [lindex $loc_info 2] + set loc_line [lindex $loc_info 3] +# debug "Got loc_info: \"$loc_info\" and filename $current(filename) long_name: $loc_long_name" + if {[string compare $current(filename) $loc_long_name] != 0} { + set not_visible 1 + } else { + foreach {name line} [lookup_line $twin 1] { + break + } + if {$line < $loc_line} { + foreach {name line} [lookup_line $twin [winfo height $twin]] { + break + } + if {$line > $loc_line} { + set not_visible 0 + } + } + } + } else { + debug "gdb_loc returned $loc_info" + } + + if {$not_visible} { + set y [expr int([winfo height $twin] / 2)] + foreach {name line addr type} [lookup_line $twin $y] { + break + } + switch $type { + src { + return [gdb_loc $name:$addr] + } + asm { + return [gdb_loc *$addr] + } + } + } else { + return $loc_info + } +} + +# ------------------------------------------------------------------ +# METHOD: lookup_line - translated win & y position line info +# +# If win is {}, or y is -1, then the saved values from the popup +# array are used. +# +# Return: +# name - the fileName +# line - the line number in the text widget +# addr - the source line number, if in source mode, the +# address if in assembly mode, and if in mixed mode, +# the line if it is a source line, or the address if it +# is an assembly line +# type - src if it is a source line, asm if an assembly line. +# set_cmd - for convenience, this is the command needed to set a +# breakpoint at this address. +# ------------------------------------------------------------------ +body SrcTextWin::lookup_line {win y} { + #debug "$win $y" + if {$y == -1} { + set y $popups(saved_y) + } + + if {$win == {}} { + set win $popups(saved_win) + } + + scan [$win index @0,$y] "%d." line + set name [lindex [::file split $current(filename)] end] + + # If we are in the SOURCE window (either because the mode is SOURCE, + # or SRC+ASM, and we are in the upper pane, then return the + if {([string compare $current(mode) SOURCE] == 0) + || ([string compare $current(mode) SRC+ASM] == 0 + && [string compare $win $twin] == 0)} { + set addr $line + set type "src" + } else { + if {[info exists _map($Cname,line=$line)]} { + set addr $_map($Cname,line=$line) + set type "asm" + } else { + # This is a source line in MIXED mode + set line_contents [$win get $line.0 "$line.0 lineend"] + #debug "Looking at line: $line contents: \"$line_contents\"" + regexp "^\t(\[0-9\]*)" $line_contents match srcline + set addr $srcline + set type "src" + } + } + + switch $type { + asm { + set set_cmd [list gdb_set_bp_addr $addr] + } + src { + set set_cmd [list gdb_set_bp $current(filename) $addr] + } + } + + #debug "Lookup line returning [list $name $line $addr $type $set_cmd]" + return [list $name $line $addr $type $set_cmd] +} + +# ------------------------------------------------------------------ +# METHOD: continue_to_here - Advance to the line pointed to by the +# y coordinate in the window win. If win is {} or y is -1, the values +# saved in the popups array are used. +# +# The threads parameter is not currently used. +# ------------------------------------------------------------------ +body SrcTextWin::continue_to_here {{win {}} {y -1} {threads -1}} { + + # Look up the line... This foreach is an lassign... + foreach {name line addr type set_cmd} [lookup_line $win $y] { + break + } + + set dont_change_appearance 1 + foreach i [gdb_get_breakpoint_list] { + set enabled($i) [lindex [gdb_get_breakpoint_info $i] 5] + } + gdb_cmd "disable" + eval $set_cmd temp $threads + gdb_immediate "continue" + gdb_cmd "enable" + foreach i [gdb_get_breakpoint_list] { + if {![info exists enabled($i)]} { + gdb_cmd "delete $i" + } elseif {!$enabled($i)} { + gdb_cmd "disable $i" + } + } + set dont_change_appearance 0 +} + +# ------------------------------------------------------------------ +# METHOD: set_bp_at_line - called when an empty break tag is clicked on +# +# When "threads" is set it means to set a bp on each thread in the list. +# ------------------------------------------------------------------ +body SrcTextWin::set_bp_at_line {{type N} {win {}} {y -1} {threads "-1"}} { +# debug "$win $y $type $current(filename) Tracing=$Tracing" + if {$Running} {return} + + # Look up the line... This foreach is an lassign... + + foreach {name line addr addr_type set_cmd} [lookup_line $win $y] { + break + } + + foreach th $threads { + switch $type { + N { + if {[catch {eval $set_cmd normal $th} msg]} { + dbug W $msg + } + } + T { + if {[catch {eval $set_cmd temp $th} msg]} { + dbug W $msg + } + } + } + } +} + +# ------------------------------------------------------------------ +# METHOD: remove_bp_at_line - called when a bp tag is clicked on +# +# when "threads" is set it means to set a bp on each thread in the list. +# ------------------------------------------------------------------ +body SrcTextWin::remove_bp_at_line {{win {}} {y -1}} { + + if {$Running} {return} + + # Look up the line... This foreach is an lassign... + + foreach {name line addr type} [lookup_line $win $y] { + break + } + + if {[string compare $type src] == 0} { + gdb_cmd "clear $name:$addr" + } else { + gdb_cmd "clear *$addr" + } +} + + +# ------------------------------------------------------------------ +# METHOD: set_tp_at_line - called when an empty break region tag is clicked on +# +# when "threads" is set it means to set a bp on each thread in the list. +# ------------------------------------------------------------------ +body SrcTextWin::set_tp_at_line {{win {}} {y -1}} { +# debug "$win $y $current(filename) Tracing=$Tracing" + + if {$Running} {return} + + # Look up the line... This foreach is an lassign... + + foreach {name line addr type} [lookup_line $win $y] { + break + } + + switch $type { + src { + after idle [list ManagedWin::open TraceDlg -File $name -Lines $addr] + } + asm { + after idle [list ManagedWin::open TraceDlg -File $name -Addresses [list $addr]] + } + } +} + +# ------------------------------------------------------------------ +# METHOD: next_hit_at_line - Finds the next trace hit at the line +# given by win & y... +# +# ------------------------------------------------------------------ +body SrcTextWin::next_hit_at_line {{win {}} {y -1}} { +# debug "$win $y $current(filename) Tracing=$Tracing" + + if {!$Browsing} {return} + + # Look up the line... This foreach is an lassign... + + foreach {name line addr type} [lookup_line $win $y] { + break + } + + # If the line and the addr are the same, then the specification was + # given by line. Otherwise is was a memory address. + + switch $type { + src { + tfind_cmd "tfind line $name:$addr" + } + asm { + tfind_cmd "tfind line *$addr" + } + } + +} + +# ------------------------------------------------------------------ +# METHOD: remove_tp_at_line - called when a tp tag is clicked on +# +# when "threads" is set it means to set a bp on each thread in the list. +# ------------------------------------------------------------------ +body SrcTextWin::remove_tp_at_line {{win {}} {y -1}} { + + if {$Running} {return} + + # Look up the line... This foreach is an lassign... + + foreach {name line addr type} [lookup_line $win $y] { + break + } + switch $type { + src { + set tp_num [gdb_tracepoint_exists $name:$addr] + } + asm { + set tp_num [gdb_tracepoint_exists *$addr] + } + } + + if {$tp_num != -1} { + if {[catch {gdb_cmd "delete tracepoints $tp_num"} errTxt]} { + tk_messageBox -type error -message "Could not delete tracepoint number $tp_num +Error was: $errTxt" + } + } + +} + +# ------------------------------------------------------------------ +# METHOD: do_tag_popup - The tag bind function for breakpoint popups +# ------------------------------------------------------------------ + +body SrcTextWin::do_tag_popup {name X Y y} { + +# debug "$name $X $Y $y" + + if {$Running || [winfo ismapped $popups($name)]} { + return + } + + set popups(saved_y) $y + set popups(saved_win) [winfo containing -displayof $itk_interior $X $Y] + + # Hide variable balloons before showing the popup + $twin tag remove _show_variable 1.0 end + balloon withdraw $twin + + tk_popup $popups($name) $X $Y + +} + +# ------------------------------------------------------------------ +# METHOD: do_source_popup - tag bind function for source popups +# ------------------------------------------------------------------ + +body SrcTextWin::do_source_popup { X Y x y } { + if {$Running || [winfo ismapped $popups(source)]} { + return + } + + # Figure out what window we are over... + set win [winfo containing -displayof $itk_interior $X $Y] + + # Hide variable balloons before showing the popup + $win tag remove _show_variable 1.0 end + balloon withdraw $win + catch {$_balloon_var delete} + + + # Try to get the selection. If you fail, get the word around the + # click point. + # Note that we don't have to worry about the user clicking over the + # break area, since the break_rgn_tag will override this... + + set hit_point [$win index @$x,$y] + if {([$win tag ranges sel] != "") + && ([$win compare sel.first < $hit_point] + && [$win compare $hit_point < sel.last])} { + set sel_first [$win index sel.first] + set sel_last [$win index sel.last] + + # If there was a selection, see if it spans multiple lines. + scan $sel_first "%d.%d" range_low sel_start_char + scan $sel_last "%d.%d" range_high sel_end_char + + if {$range_low == $range_high} { + set range -1 + set target_range [$win get sel.first sel.last] + } else { + # If the selection encompasses multiple lines, we only care about + # the start and ending line numbers + set range 1 + } + } else { + set target_range [$win get "$hit_point wordstart" "$hit_point wordend"] + set range 0 + } + + $popups(source) delete 0 end + + if {$range && $Tracing} { + # If the selection spans more than one line, it can't be a variable name... + # So just insert the tracepoint range item + $popups(source) add command -label "Set Tracepoint Range" \ + -command "$this tracepoint_range $win $range_low $range_high" + $popups(source) add separator + } elseif {$range != 1} { + # RANGE = -1 means that we have already found the word we want (it was + # a selection)... + # RANGE = 1 means we got the word around the point, and we are just saving + # getVariable the trouble of parsing it again. + if {$range == -1} { + set variable $target_range + } else { + set variable [lindex [getVariable -1 -1 $target_range] 0] + } + + if {$variable != ""} { + # LAME: check to see if VARIABLE is really a number (constants??) + set is_var [catch {expr {$variable+1}}] + + if {$is_var} { + $popups(source) add command -label "Add $variable to Watch" \ + -command [list $this addToWatch $variable] + $popups(source) add command -label "Dump Memory at $variable" \ + -command [list ManagedWin::open MemWin -force -addr_exp $variable] + $popups(source) add separator + } + } + } + + $popups(source) add command -label "Open Another Source Window" \ + -command {ManagedWin::open SrcWin -force} + if {[info exists ::enable_external_editor] && $::enable_external_editor} { + $popups(source) add command -label "Open Source in external editor" \ + -command [list $parent edit] + } + + tk_popup $popups(source) $X $Y +} + +# ------------------------------------------------------------------ +# METHOD: addToWatch - add a variable to the watch window +# ------------------------------------------------------------------ +body SrcTextWin::addToWatch {var} { + [ManagedWin::open WatchWin] add $var +} + +# ------------------------------------------------------------------ +# METHOD: do_key -- wrapper for all key bindings +# ------------------------------------------------------------------ +body SrcTextWin::do_key {key} { + if {!$Running} { + switch $key { + print { print } + download { Download::download_it } + run { $parent inferior run } + stack { ManagedWin::open StackWin } + registers { ManagedWin::open RegWin } + memory { ManagedWin::open MemWin } + watch { ManagedWin::open WatchWin } + locals { ManagedWin::open LocalsWin } + breakpoints { ManagedWin::open BpWin } + console { ManagedWin::open Console } + step { $parent inferior step } + next { $parent inferior next } + finish { $parent inferior finish } + continue { $parent inferior continue } + stepi { $parent inferior stepi } + nexti { $parent inferior nexti } + up { catch {gdb_cmd up} } + down { catch {gdb_cmd down} } + quit { gdbtk_quit } + tdump { ManagedWin::open TdumpWin } + tracepoints { ManagedWin::open BpWin -tracepoints 1} + tfind_next { catch {gdb_immediate tfind} } + tfind_prev { catch {gdb_immediate "tfind -"} } + tfind_start { catch {gdb_immediate "tfind start"} } + tfind_line { catch {gdb_immediate "tfind line"} } + tfind_tp { catch {gdb_immediate "tfind tracepoint"} } + open { catch {_open_file} } + browser { catch {ManagedWin::open BrowserWin} } + thread_list { catch {ManagedWin::open ProcessWin} } + debug { catch {ManagedWin::open DebugWin} } + kod { catch {ManagedWin::open KodWin} } + default { + dbug E "Unknown key binding: \"$key\"" + } + } + } else { +# debug "ignoring keypress -- running" + } +} + +# ------------------------------------------------------------------ +# METHOD: mode_get - get the source mode +# ------------------------------------------------------------------ +body SrcTextWin::mode_get {} { + return $current(mode) +} + +# ------------------------------------------------------------------ +# METHOD: mode_set - change the source mode +# ------------------------------------------------------------------ +body SrcTextWin::mode_set {new_mode {go 1}} { +# debug "$new_mode" + + if {$new_mode != $current(mode)} { + + if {$current(mode) == "SRC+ASM"} { + if {$_bpane != ""} {$itk_interior.p hide $_bpane} + set _bpane "" + set _bwin "" + } + + set current(mode) $new_mode + set mode_changed 1 + + if {$go} { + location $current(tag) $current(filename) $current(funcname) \ + $current(line) $current(addr) $pc(addr) $current(lib) + } + } +} + +# ------------------------------------------------------------------ +# METHOD: cancelMotion - cancel any pending motion callbacks for +# the source window's variable balloons +# ------------------------------------------------------------------ +body SrcTextWin::cancelMotion {} { + catch {after cancel $timeoutID} +} + +# ------------------------------------------------------------------ +# METHOD: motion - callback for mouse motion within the source +# window's text widget +# ------------------------------------------------------------------ +body SrcTextWin::motion {type win x y} { + global gdb_running + cancelMotion + + # The showBalloon method can sometimes raise errors (for instance in + # assembly code with no sources, and when gdb coughs over a path + # that contains a space. These functions should error quietly. + # but write to the debug window so we can trace problems. + + if {$type == "var"} { + set cmd_bit "" + } else { + set cmd_bit BP + } + set cmd_line [format { + if {[catch {%s show%sBalloon %s %d %d} err]} { + debug "show%sBalloon got error: $err" + } + } $this $cmd_bit $win $x $y $cmd_bit] + set timeoutID [after $TimeOut $cmd_line] +} + + +# ------------------------------------------------------------------ +# METHOD: showBPBalloon - show BP information in a balloon +# ------------------------------------------------------------------ +body SrcTextWin::showBPBalloon {win x y} { + if {$Running} { return } + $win tag remove _show_variable 1.0 end + set line [lindex [split [$win index @0,$y] .] 0] + set bps "" + + switch $current(mode) { + SRC+ASM { + if {$win == $bwin} { + if {[info exists _map($Cname,line=$line)]} { + set addr $_map($Cname,line=$line) + set bps [gdb_find_bp_at_addr $addr] + } else { + return + } + } + } + ASSEMBLY { + if {[info exists _map($Cname,line=$line)]} { + set addr $_map($Cname,line=$line) + set bps [gdb_find_bp_at_addr $addr] + } else { + return + } + } + MIXED { + if {[info exists _map($Cname,line=$line)]} { + set addr $_map($Cname,line=$line) + set bps [gdb_find_bp_at_addr $addr] + } else { + return + } + } + } + + if {$bps == ""} { + set bps [gdb_find_bp_at_line $current(filename) $line] + } + + set str "" + set need_lf 0 + foreach b $bps { + set bpinfo [gdb_get_breakpoint_info $b] + lassign $bpinfo file func linenum addr type enabled disposition \ + ignore_count commands cond thread hit_count + if {$thread == "-1"} {set thread "all"} + set file [lindex [file split $file] end] + if {$enabled} { + set enabled "ENA" + } else { + set enabled "DIS" + } + if {$cond == ""} {set cond "none"} + if {$need_lf} { + append str \n + } else { + set need_lf 1 + } + append str [format "breakpoint %d at %s:%d (%#x)\n\t%s %s %s %s %s" \ + $b $file $linenum $addr $enabled $type $disposition \ + threads=$thread cond=$cond] + } + + # Scope out which break type is set here, and use the tag to get + # the break region range... + + set tag_list [$win tag names $line.0] + set break_tag [lindex $tag_list [lsearch -glob $tag_list *bp_tag]] + set end [lindex [$win tag nextrange $break_tag $line.0 $line.end] 1] + + if {$end != ""} { + $win tag add _show_variable $line.0 $end + balloon register $win $str _show_variable + balloon show $win _show_variable 1 + } +} + +# ------------------------------------------------------------------ +# METHOD: showBalloon - (possibly) show a variable's value in +# a balloon-help widget +# ------------------------------------------------------------------ +body SrcTextWin::showBalloon {win x y} { + if {$Running} { return } + + $twin tag remove _show_variable 1.0 end + catch {tmp delete} + + + if {[catch {getVariable $x $y} variable]} { + return + } + + if {[llength $variable] != 3} { + return + } + + # We get the variable name, and its start and stop indices in the text + # widget, so all we need to do is set the tag and register the balloon help + set varName [lindex $variable 0] + set start [lindex $variable 1] + set stop [lindex $variable 2] + + # Get the address associated with this line + foreach {file text_line source_line type} [lookup_line $twin $y] { + break + } + + # Reduce the areas over which we will show balloons. + # 1) Only pop up a balloon if we are over the function in + # the currently selected frame, or in the static data for + # the file. + # 2) We would also like to exclude cases where the line that + # under the mouse cursor does not contain executable code, + # but we can't since gdb considers continuation lines to not + # have executible code so we would lose on these... + + set cur_fn [lindex [gdb_loc $file:$source_line] 1] + set selected_frame_fn [lindex [gdb_loc] 1] + + if {[string compare $cur_fn $selected_frame_fn] == 0} { + # Create the variable object + catch {$_balloon_var delete} + set err [catch {gdb_variable create -expr $varName} _balloon_var] + if {!$err} { + set value [balloon_value $_balloon_var] + if {$value != ""} { + $win tag add _show_variable $start $stop + + # display variable's value + balloon register $twin "$varName=$value" _show_variable + balloon show $win _show_variable + } else { + # No value/error. Don't show it. + catch {$_balloon_var delete} + set _balloon_var {} + } + } else { + set _balloon_var {} + } + } else { + set _balloon_var {} + } +} + +# ------------------------------------------------------------------ +# METHOD: getVariable - get the name of the 'variable' under the +# mouse pointer in the text widget +# ------------------------------------------------------------------ +body SrcTextWin::getVariable {x y {line {}}} { + #debug "$x $y $line" + set hit_point [$twin index @$x,$y] + + if {$x != -1 && $y != -1} { + # If we are over a selection, just report that: + if {([$twin tag ranges sel] != "") + && ([$twin compare sel.first < $hit_point] + && [$twin compare $hit_point < sel.last])} { + return [list [$twin get sel.first sel.last] [$twin index sel.first] [$twin index sel.last]] + } + # Since we will only be concerned with this line, get it + set line [$twin get "$hit_point linestart" "$hit_point lineend"] + # debug "new line=$line" + set simple 0 + } else { + # This is not quite right -- still want constants to appear... + set simple 1 + } + + # The index into LINE that contains the char at which the pointer hangs + set a [split [$twin index @$x,$y] .] + set lineNo [lindex $a 0] + set index [lindex $a 1] + set s [string range $line $index end] + set last {} + foreach char [split $s {}] { + if {[regexp -- {([^a-zA-Z0-9_>.-])} $char dummy]} { + break + } + lappend last $char + } + set last [string trimright [join $last {}] ->] + + # Decrement index for string -- will need to increment it later + incr index -1 + set tmp [string range $line 0 $index] + set s {} + foreach char [split $tmp {}] { + set s [linsert $s 0 $char] + } + + set first {} + foreach char $s { + if {[regexp -- {([^a-zA-Z0-9_>.-])} $char dummy]} { + break + } + set first [linsert $first 0 $char] + } + #set first [string trimleft [join $first {}] ->] + set first [join $first {}] + #debug "FIRST=$first\nLAST=$last" + + # Validate the variable + set variable [string trim $first$last \ ] + if {!$simple && ![regexp {^[a-zA-Z_]} $variable dummy]} { + #debug "Rejecting: $variable" + return {} + } + + incr index + # Find the boundaries of this word in the text box + set a [string length $first] + set b [string length $last] + + # Gag! If there is a breakpoint at a line, this is off by one! + if {[hasBP $twin $lineNo] || [hasTP $twin $lineNo]} { + incr a -1 + incr b 1 + } + set start "$lineNo.[expr {$index - $a}]" + set end "$lineNo.[expr {$index + $b}]" + return [list $variable $start $end] +} + +# ------------------------------------------------------------------ +# METHOD: trace_help - update statusbar with ballon help message +# ------------------------------------------------------------------ +body SrcTextWin::trace_help {args} { + upvar #0 ${this}_balloon a + if {$a == ""} { + $parent set_status + } else { + $parent set_status $a 1 + } +} + +body SrcTextWin::line_is_executable {win line} { + # there should be an image or a "-" on the line + set res [catch {$win image cget $line.0 -image}] + if {!$res || [$win get $line.0] == "-"} { + return 1 + } + return 0 +} + +# ------------------------------------------------------------------ +# METHOD: tracepoint_range - create tracepoints at every line in +# a range of lines on the screen +# ------------------------------------------------------------------ +body SrcTextWin::tracepoint_range {win low high} { +# debug "$win $low $high" + + switch $current(mode) { + SOURCE { + set lines {} + for {set i $low} {$i <= $high} {incr i} { + if {[line_is_executable $win $i]} { + lappend lines $i + } + } + } + + ASSEMBLY { + set addrs {} + for {set i $low} {$i <= $high} {incr i} { + lappend addrs $_map($Cname,line=$i) + } + } + + MIXED { + set addrs {} + for {set i $low} {$i <= $high} {incr i} { + if {[line_is_executable $win $i]} { + lappend addrs $_map($Cname,line=$i) + } + } + } + + SRC+ASM { + if {$win == $awin} { + # Assembly + set addrs {} + for {set i $low} {$i <= $high} {incr i} { + lappend addrs $_map($Cname,line=$i) + } + } else { + # Source + set lines {} + for {set i $low} {$i <= $high} {incr i} { + if {[line_is_executable $win $i]} { + lappend lines $i + } + } + } + } + } + + if {[info exists lines]} { +# debug "Got executible lines: $lines" + if {[llength $lines]} { + set name [::file tail $current(filename)] + ManagedWin::open TraceDlg -File $name -Lines $lines + } + } elseif {[info exists addrs]} { +# debug "Got executible addresses: $addrs" + if {[llength $addrs]} { + set name [::file tail $current(filename)] + ManagedWin::open TraceDlg -File $name -Addresses $addrs + } + } else { +# debug "Got no executible lines in the selected range..." + } + + # Clear the selection -- it looks a lot better. + $twin tag remove sel 1.0 end +} + + +# ------------------------------------------------------------------ +# METHOD: search - search for text or jump to a specific line +# in source window, going in the specified DIRECTION. +# ------------------------------------------------------------------ +body SrcTextWin::search {exp direction} { + if {$exp != ""} { + set result {} + if {[regexp {^@([0-9]+)} $exp dummy index]} { + append index .0 + set end [$twin index "$index lineend"] + } else { + set index [$twin search -exact -count len -$direction -- $exp $SearchIndex] + + if {$index != ""} { + set end [split $index .] + set line [lindex $end 0] + set char [lindex $end 1] + set char [expr {$char + $len}] + set end $line.$char + set result "Match of \"$exp\" found on line $line" + if {$direction == "forwards"} { + set SearchIndex $end + } else { + set SearchIndex $index + } + } + } + if {$index != ""} { + # Highlight word and save index + $twin tag remove search 1.0 end + $twin tag add search $index $end + $twin see $index + } else { + set result "No match for \"$exp\" found" + } + return $result + } else { + $twin tag remove search 1.0 end + } +} + +# ----------------------------------------------------------------------------- +# NAME: SrcTextWin::LoadFromCache +# +# SYNOPSIS: LoadFromCache {w name asm lib} +# +# DESC: Looks up $name in the cache. If $name is cached, replace the +# pane $w with the cached pane. Otherwise create a new +# pane and scrolledtext widget and set _${w}pane and _${w}win. +# +# ARGS: w "t" or "b" (for Top and Bottom pane) +# name name to look for in cache. This will be a filename if +# we are filling in a source window, or an address +# otherwise. +# asm 'A' for assembly mode, 'M' for mixed mode. +# lib library name +# +# RETURNS: 0 - read from cache +# 1 - created new (blank) widget +# +# NOTES: If you call this and a new widget is created which cannot be +# filled in later due to errors, call UnLoadFromCache. +# ----------------------------------------------------------------------------- +body SrcTextWin::LoadFromCache {w name asm lib} { + debug "LoadFromCache $w $name $asm" + upvar ${w}win win + upvar _${w}pane pane + + if {[string compare gdbtk_scratch_widget $name]} { + append full_name $name "," $asm "," $lib + } else { + set full_name $name + } + + set oldpane $pane + if {[info exists Stwc($full_name:pane)]} { + #debug "READING CACHE $full_name->$Stwc($full_name:pane)" + set pane $Stwc($full_name:pane) + if {$oldpane != ""} { + $itk_interior.p replace $oldpane $pane + } else { + $itk_interior.p show $pane + } + set win [[$itk_interior.p childsite $pane].st component text] + if {$asm != ""} { + set Cname $full_name + } + + # If the text in this cache file is dirty, clean the window, and + # return 1, which will tell the caller to refill it. Otherwise + # return 0, and the caller will just display the window. + + if {$Stwc($name:dirty)} { + $win delete 0.0 end + set res 1 + set Stwc($name:dirty) 0 + } else { + set res 0 + } + + } else { + #debug "name=$name" + set Stwc($full_name:pane) pane$filenum + # Sometimes we get in here with no source file, in which case + # name is a hex address. Catch the error from this. + if {[catch {file mtime $name} file_time]} { + debug "Could not stat file: $name in LoadFromCache: $file_time" + set Stwc($name:mtime) 0 + } else { + set Stwc($name:mtime) $file_time + } + + set Stwc($name:dirty) 0 + incr filenum + + set pane $Stwc($full_name:pane) + debug "pane=$pane" + if {$oldpane != ""} {$itk_interior.p hide $oldpane} + $itk_interior.p add $pane + set p [$itk_interior.p childsite $pane] + set st [iwidgets::scrolledtext $p.st \ + -hscrollmode dynamic -vscrollmode dynamic] + set win [$st component text] + + if {$asm != ""} { + set Cname $full_name + } + pack $st -expand yes -fill both + set res 1 + } + + # reconfigure in case some preferences have changed + config_win $win $asm + return $res +} + +# ------------------------------------------------------------------ +# METHOD: UnLoadFromCache - revert back to previously cached widget +# This is used when a new widget is created with LoadFromCache but +# there is a problem with filling the widget. +# ------------------------------------------------------------------ + +body SrcTextWin::UnLoadFromCache {w oldpane name asm lib} { +# debug "$w $oldpane $name" + upvar ${w}win win + upvar _${w}pane pane +# debug "pane=$pane win=$win" + + append name "," $asm "," $lib + $itk_interior.p delete $pane + unset Stwc($name:pane) + unset Stwc($name:dirty) + unset Stwc($name:mtime) + $itk_interior.p show $oldpane + set pane $oldpane + set win [[$itk_interior.p childsite $pane].st component text] +} + +# ------------------------------------------------------------------ +# METHOD: print - print the contents of the text widget +# ------------------------------------------------------------------ +body SrcTextWin::print {top} { + # FIXME + send_printer -ascii [$twin get 1.0 end] -parent $top +} + +# ------------------------------------------------------------------ +# METHOD: ask_thread_bp - prompt for thread(s) for BP +# ------------------------------------------------------------------ +body SrcTextWin::ask_thread_bp {} { +# debug + if {[catch {gdb_cmd "info thread"} threads]} { + # failed. Just leave + return + } + set threads [split $threads \n] + set num_threads [expr {[llength $threads] - 1}] + if {$num_threads <= 0} { + show_warning "No threads were found.\nYou may only set breakpoints on threads\nthat have already been created." + return + } + + set a [toplevel .[gensym]] + wm title $a "Thread Selection" + CygScrolledListbox $a.slb -selectmode multiple -height $num_threads + + set i [expr $num_threads - 1] + set width 0 + foreach line $threads { + # Active line starts with "*" + if {[string index $line 0] == "*"} { + # strip off leading "*" + set line " [string trimleft $line "*"]" + } + # scan for GDB ID number at start of line + if {[scan $line "%d" id($i)] == 1} { + if {[string length $line] > $width} { + set width [string length $line] + } + $a.slb.list insert 0 $line + incr i -1 + } + } + $a.slb.list configure -width $width + + frame $a.b + button $a.b.ok -text OK -underline 0 -width 7 \ + -command "$this do_thread_bp $a.slb.list" + button $a.b.cancel -text Cancel -width 7 -underline 0 -command "destroy $a" + pack $a.b.ok $a.b.cancel -side left + standard_button_box $a.b + pack $a.b -fill x -expand yes -side bottom -padx 5 -pady 5 + pack $a.slb -side top -fill both -expand yes + bind $a.b.ok <Return> "$a.b.ok flash; $a.b.ok invoke" + focus $a.b.ok +} + +# ------------------------------------------------------------------ +# METHOD: do_thread_bp - callback from thread selection +# ------------------------------------------------------------------ +body SrcTextWin::do_thread_bp {listbox} { +# debug "$listbox [$listbox curselection]" + set x "" + foreach i [$listbox curselection] { + lappend x $id($i) + } + $this set_bp_at_line N {} -1 $x + destroy [winfo toplevel $listbox] +} + + +# public method for testing use only! +body SrcTextWin::test_get {var} { + if {[array exists $var]} { + return [array get $var] + } else { + return [set $var] + } +} + +# ------------------------------------------------------------------ +# METHOD: clear_file - Clear out state so that user may load +# new executable. For the SrcTextWin class, this means: +# +# Delete all srctextwin caches +# Delete the variable balloon if it exists. +# Clear the screen. +# ------------------------------------------------------------------ +body SrcTextWin::clear_file {} { + + debug "In clear_file" + # delete all caches + _clear_cache + + set oldpane {} + + # clear window + # FIXME - We don't do this here, because is causes a wierd error + # where the "Source file more recent than executible" error gets + # for no apparent reason. This only effects the case where the + # user types just "file" in the command line, then the window will + # not get cleared. + + # delete variable balloon + catch {$_balloon_var delete} + set _balloon_var {} + + # reinit state + _initialize_srctextwin + + # update the screen + update idletasks + +} + +body SrcTextWin::_initialize_srctextwin {} { + set pc(filename) "" + set pc(func) "" + set pc(line) 0 + set pc(addr) "" + set pc(asm_line) 0 + set pc(lib) "" + set current(filename) "" + set current(funcname) "" + set current(line) 0 + set current(addr) "" + set current(asm_line) 0 + set current(tag) "BROWSE_TAG" + set current(mode) "SOURCE" + set current(lib) "" +} + +# ------------------------------------------------------------------ +# METHOD: _clear_cache - Clear the cache +# ------------------------------------------------------------------ +body SrcTextWin::_clear_cache {} { + # This doesn't work, and it's so darn entangled that it's nearly + # impossible. + return + + # display empty scratch frame + set pane $Stwc(gdbtk_scratch_widget:pane) + set win [[$itk_interior.p childsite $pane].st component text] + $win delete 0.0 end + $itk_interior.p show $pane + + # delete all cached frames + foreach p [array names Stwc *:pane] { + set p [lindex [split $p :] 0] + if {$p != "gdbtk_scratch_widget"} { + catch {$itk_interior.p delete $Stwc($p:pane)} + unset Stwc($p:pane) + unset Stwc($p:mtime) + } + } +} + + diff --git a/gdb/gdbtk/library/srctextwin.ith b/gdb/gdbtk/library/srctextwin.ith new file mode 100644 index 00000000000..a9f2bfbb825 --- /dev/null +++ b/gdb/gdbtk/library/srctextwin.ith @@ -0,0 +1,156 @@ +# SrcTextWin class definition, for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class SrcTextWin { + inherit itk::Widget + + public { + variable Tracing ;# 1 if we are running in trace mode + variable Browsing 0 ;# 1 if we are browsing a trace experiment + variable parent {} ;# the parent SrcWin + variable ignore_var_balloons 0; # ignore all variable balloons + + # Set the height of the src window + variable textheight 5i { + catch {$itk_interior.p configure -height $itk_option(-textheight)} + } + + method constructor {args} + method destructor {} + method disassembly_changed {} + method reconfig {} + method trace_find_hook {mode from_tty} + method set_control_mode {mode} + method build_popups {} + method build_win {} + method SetRunningState {state} + method enable {on} + method setTabs {win {asm ""}} + method enable_disable_src_tags {win how} + method config_win {win {asm ""}} + method addPopup {menu label command {abg {}} {browse 1} {run 1}} + method updateBalloon {} + method ClearTags {} + method FillSource {winname tagname filename funcname line addr pc_addr lib} + method FillAssembly {winname tagname filename funcname line addr pc_addr lib} + method FillMixed {winname tagname filename funcname line addr pc_addr lib} + method location {tagname filename funcname line addr pc_addr lib} + method LoadFile {winname name lib mtime_changed} + method display_line { win line } + method display_breaks {} + method insertBreakTag {win linenum tag} + method removeBreakTag {win linenum tag } + method bp {action bpnum addr {linenum {}} {file {}} {type 0} {enabled 0} {thread -1}} + method do_bp { win action linenum type bpnum enabled thread asm} + method hasBP {win line} + method hasTP {win line} + method report_source_location {} + method lookup_line {win y} + method continue_to_here {{win {}} {y -1} {threads -1}} + method set_bp_at_line {{type N} {win {}} {y -1} {threads "-1"}} + method remove_bp_at_line {{win {}} {y -1}} + method set_tp_at_line {{win {}} {y -1}} + method next_hit_at_line {{win {}} {y -1}} + method remove_tp_at_line {{win {}} {y -1}} + method do_tag_popup {name X Y y} + method do_source_popup { X Y x y } + method addToWatch {var} + method do_key {key} + method mode_get {} + method mode_set {new_mode {go 1}} + method cancelMotion {} + method motion {type win x y} + method showBPBalloon {win x y} + method showBalloon {win x y} + method getVariable {x y {line {}}} + method trace_help {args} + method line_is_executable {win line} + method tracepoint_range {win low high} + method search {exp direction} + method LoadFromCache {pname name asm lib} + method UnLoadFromCache {pname oldpane name asm lib} + method print {top} + method ask_thread_bp {} + method do_thread_bp {listbox} + method test_get {var} + method clear_file {} + } + + protected { + method handle_set_hook {var val} + } + private { + variable top ;# toplevel window + variable twin ;# top text window of pane + variable _tpane ;# top pane name + variable bwin "" ;# bottom text window of pane + variable _bpane "" ;# bottom pane name + + variable do_display_breaks 0 ;# flag + variable popups + + variable timeoutID {} ;# The timeout ID for the variable balloon help + variable UseVariableBalloons + + variable mode_changed 0 + variable current ;# our current state + variable pc ;# where the PC is now + variable oldmode "" ;# remember the mode we want, even if we can't have it + + variable Running 0 ;# another way to disable things while target is active + variable Linenums ;# use linenumbers? + variable SearchIndex 1.0 ;# static + variable id ;#thread id to line mapping + # needed for assembly support + variable _map + variable Cname "" ;# cache index name for _map + # cache is not shared among windows yet. That could be a later + # optimization + variable Stwc ;# Source Text Window Cache + variable filenum 0 + + # The variable object which the variable balloon describes + variable _balloon_var {} + + method balloon_value {variable} + method _mtime_changed {filename} + method _initialize_srctextwin {} + method _clear_cache {} + + proc makeBreakDot {size colorList {image {}}} + } + + + + # common variables are shared among all objects of this type + # break_images stores the images associated with the break dot. + # bp + # temp_bp + # disabled_bp + # tp + # thread_bp + protected common break_images + + # This is the list of bp types. Be nice, and don't put spaces in + # any of the elements of this list... + protected common bp_types {bp temp_bp disabled_bp thread_bp} + + # This variable is used in the "Continue to here" case, where we are + # disabling then reenabling breakpoints behind the user's back to + # implement this feature, but we don't want the user to see this... + protected common dont_change_appearance 0 + + protected common TimeOut 100 ;# The timeout value for variable balloon help + +} diff --git a/gdb/gdbtk/library/srcwin.itb b/gdb/gdbtk/library/srcwin.itb new file mode 100644 index 00000000000..a822c5deae7 --- /dev/null +++ b/gdb/gdbtk/library/srcwin.itb @@ -0,0 +1,870 @@ +# Source window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new source window +# ------------------------------------------------------------------ +body SrcWin::constructor {args} { + debug "$args" + eval itk_initialize $args + set top [winfo toplevel $itk_interior] + + _update_title "" + + # On Windows, create a sizebox. + if {$::tcl_platform(platform) == "windows"} { + ide_sizebox $itk_interior.sizebox + } + + set Tracing [pref get gdb/mode] + set current(filename) "" + + if {[catch {_build_win} mssg]} { + dbug E "_build_win returned: $::errorInfo" + } + + # add special delete handler + wm protocol $top WM_DELETE_WINDOW "[code $this _exit]" + + # add hooks + add_hook gdb_update_hook "$this update" + add_hook gdb_busy_hook "$this busy" + add_hook gdb_idle_hook "$this idle" + add_hook gdb_no_inferior_hook "$this no_inferior" + add_hook download_progress_hook "$this download_progress" + add_hook state_hook [code $this _set_state] + add_hook gdb_clear_file_hook [code $this clear_file] + after idle " + update idletasks + $this sizeWinByChild toolbar" +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body SrcWin::destructor {} { + debug + remove_hook gdb_update_hook "$this update" + remove_hook gdb_busy_hook "$this busy" + remove_hook gdb_no_inferior_hook "$this no_inferior" + remove_hook gdb_idle_hook "$this idle" + remove_hook download_progress_hook "$this download_progress" + remove_hook state_hook [code $this _set_state] + remove_hook gdb_clear_file_hook [code $this clear_file] +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: _build_win - build the main source window +# ------------------------------------------------------------------ +body SrcWin::_build_win {} { + global gdb_downloading gdb_running gdb_loaded + + # build source toolbar + set _toolbar [conAdd toolbar -resizable 0] + GDBSrcBar $_toolbar $this \ + -updatecommand [list $this toggle_updates] \ + -updatevalue $do_updates + + # add a SrcTextWin container + set srcwin [conAdd src] + set twin [SrcTextWin $srcwin -Tracing $Tracing -parent $this] + pack $srcwin -expand 1 -fill both + + # add status line + set _status [conAdd status -resizable 0] + label $_status -relief sunken -bd 3 -font global/status -height 1 + pack $_status -expand 1 -fill both + + # add a status bar container + set _statbar [conAdd stat -resizable 0] + frame $_statbar + pack $_statbar -expand 1 -fill both + + combobox::combobox $_statbar.name -maxheight 15 -font src-font\ + -command [code $this _name] + + set need_files 1 + + combobox::combobox $_statbar.func -maxheight 15 -font src-font\ + -command [code $this goto_func] + combobox::combobox $_statbar.mode -width 9 -editable false \ + -font src-font -command [code $this mode] + + $_statbar.mode list insert end SOURCE + $_statbar.mode list insert end ASSEMBLY + $_statbar.mode list insert end MIXED + $_statbar.mode list insert end SRC+ASM + + + # Search/download progress frame + frame $_statbar.frame + entry $_statbar.frame.search -bd 3 -font src-font -width 10 + bind_plain_key $_statbar.frame.search \ + Return [code $this _search forwards] + bind_plain_key $_statbar.frame.search \ + Shift-Return [code $this _search backwards] + canvas $_statbar.frame.progress -relief sunken -borderwidth 2 \ + -highlightthickness 0 -takefocus 0 -width 100 -height 0 -confine 1 + $_statbar.frame.progress create rectangle 0 0 0 \ + [winfo height $_statbar.frame.progress] -outline blue -fill blue -tags rect + + pack $_statbar.frame -side right -pady 4 -padx 10 -fill y -expand 1 -anchor e + pack $_statbar.mode -side right -padx 10 -pady 4 + pack $_statbar.name $_statbar.func -side left -pady 4 -padx 10 + + pack $_statbar.frame.search -fill x -expand yes + + set_execution_status + + # balloon help + foreach i {entry button} { + balloon register $_statbar.name.$i "Current file name" + balloon register $_statbar.func.$i "Current function name" + balloon register $_statbar.mode.$i "Source mode" + } + balloon register $_statbar.frame.search "Search for text" + balloon variable $_status ${twin}_balloon + + $_statbar.mode entryset [$twin mode_get] + + # time to load the widget with a file. + # If this is a new widget and the program is + # not yet being debugged, load the file with "main" in it. + if {$gdb_running} { + update + } else { + if {[set linespec [gdbtk_locate_main]] != ""} { + location BROWSE_TAG $linespec + } + } +} + + +# ------------------------------------------------------------------ +# PUBLIC METHOD: _set_state - do things when program state changes +# ------------------------------------------------------------------ +body SrcWin::_set_state {varname} { + global gdb_running gdb_downloading gdb_loaded gdb_program_has_run + debug "$varname l=$gdb_loaded d=$gdb_downloading r=$gdb_running" + + if {$varname == "gdb_loaded" && $gdb_loaded == 1} { + set gdb_program_has_run 0 + #set current(filename) "" + return + } + + if {$gdb_running} { + set state normal + set gdb_program_has_run 1 + } else { + set state disabled + } + if {!$Tracing} { + $twin SetRunningState $state + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: download_progress - update the progress meter when downloading +# ------------------------------------------------------------------ +body SrcWin::download_progress { section num tot {msg ""} } { + global download_start_time download_cancel_ok gdb_loaded + + #debug "$section $num $tot $msg" + if {$last_section_start == 0} { + pack forget $_statbar.frame.search + pack $_statbar.frame.progress -fill both -expand yes + ::update idletasks + } + + if {$section == "DONE"} { + set last_done $tot + if {$gdb_loaded} { + # loaded something + set secs [expr {[clock seconds] - $download_start_time}] + if {$secs} { + set bps [expr {8 * $tot / $secs}] + set_status "DOWNLOAD FINISHED: $tot bytes in $secs seconds ($bps bits per second)" + } else { + set_status "DOWNLOAD FINISHED" + } + } + } elseif {$section != "CANCEL"} { + if {$section != $last_section} { + set last_section $section + set last_section_start $last_done + } + set last_done [expr {$last_section_start + $num}] + set_status "Downloading section $section - $num bytes" + } + + set canvas $_statbar.frame.progress + set height [winfo height $canvas] + if {$last_done} { + set width [winfo width $canvas] + set rw [expr {double ($last_done) * $width / $tot}] + $canvas coords rect 0 0 $rw $height + ::update + } + + if {$last_done == $tot || $section == "CANCEL"} { + $_toolbar configure -runstop normal + if {!$gdb_loaded} { + update + # errored or canceled + if {$msg != ""} { + set_status "DOWNLOAD FAILED: $msg" + } else { + set_status "DOWNLOAD CANCELLED" + } + $canvas coords rect 0 0 0 $height + ::update idletasks + } + + set last_section "" + set last_done 0 + set last_section_start 0 + + pack forget $_statbar.frame.progress + pack $_statbar.frame.search -fill x -expand yes + ::update idletasks + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body SrcWin::reconfig {} { + debug + $_toolbar reconfig + $twin reconfig +} + + +# ------------------------------------------------------------------ +# PRIVATE METHOD: _name - filename combobox callback +# This is only called when the user edits the name combobox. +# It is the only way that files can be inserted into the file list +# once the debugger is started. +# ------------------------------------------------------------------ +body SrcWin::_name {w {val ""}} { + global _files + debug "$w $val" + if {$val != ""} { + if {![info exists _files(short,$val)]} { + if {![info exists _files(full,$val)]} { + set full [gdb_find_file $val] + if {$full == ""} { + set_status "Cannot find source file \"$val\"" + $_statbar.name entryset [lindex [file split $current(filename)] end] + return + } + set _files(short,$full) $val + set _files(full,$val) $full + } + set full $_files(full,$val) + } else { + set full $val + set val $_files(short,$full) + } + $_statbar.name entryset $val + location BROWSE_TAG [list $val "" $full 0 0 0 {}] + } +} + +# ------------------------------------------------------------------ +# PRIVATE PUBLIC METHOD: toggle_updates - update toggle callback +# ------------------------------------------------------------------ +body SrcWin::toggle_updates {value} { + if {$value} { + add_hook gdb_update_hook "$this update" + add_hook gdb_busy_hook "$this busy" + } else { + remove_hook gdb_update_hook "$this update" + remove_hook gdb_busy_hook "$this busy" + } + # save state in do_updates so it will be preserved + # in window reconfigs + set do_updates $value +} + +# ------------------------------------------------------------------ +# PRIVATE PUBLIC METHOD: goto_func - function combobox callback +# ------------------------------------------------------------------ +body SrcWin::goto_func {w {val ""}} { + if {$val != ""} { + set mang 0 + if {[info exists _mangled_func($val)]} { + set mang $_mangled_func($val) + } + if {$mang} { + set loc $val + } else { + set fn [lindex [::file split $current(filename)] end] + if {$fn == ""} { + set loc $val + } else { + set loc $fn:$val + } + } + debug "GOTO $loc" + if {![catch {gdb_loc $loc} result]} { + location BROWSE_TAG $result + } else { + dbug W "gdb_loc returned \"$result\"" + } + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: fillNameCB - fill the name combobox +# +# This method needs to be public, since other parts of +# the gui can cause new symbols to be read. +# ------------------------------------------------------------------ +body SrcWin::fillNameCB {} { + global _files + set allfiles [gdb_listfiles] + debug "gdb_listfiles returned $allfiles" + foreach f $allfiles { + #set fullname [gdb_find_file $f] + #set _files(full,$f) $fullname + #set _files(short,$fullname) $f + $_statbar.name list insert end $f + } + set need_files 0 +} + + +# ------------------------------------------------------------------ +# PUBLIC METHOD: fillFuncCB - fill the function combobox +# +# This method needs to be public, since other parts of +# the gui can cause new symbols to be read. +# ------------------------------------------------------------------ +body SrcWin::fillFuncCB {name} { + $_statbar.func list delete 0 end + if {$name != ""} { + set maxlen 10 + if {[catch {gdb_listfuncs $name} listfuncs]} { + tk_messageBox -icon error -default ok \ + -title "GDB" -type ok -modal system \ + -message "This file can not be found or does not contain\ndebugging information." + _set_name "" + return + } + foreach f $listfuncs { + lassign $f func mang + set _mangled_func($func) $mang + $_statbar.func list insert end $func + if {[string length $func] > $maxlen} { + set maxlen [string length $func] + } + } + $_statbar.func configure -width [expr $maxlen + 1] + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: location - update the location displayed +# +# a linespec looks like this: +# 0: basename of the file +# 1: function name +# 2: full filename +# 3: source line number +# 4: address +# 5: current PC - which will often be the same as address, but not when +# 6: shared library name if the pc is in a shared lib +# we are browsing, or walking the stack. +# +# linespec will be "{} {} {} 0 0x0 0x0" when GDB has not started debugging. +# ------------------------------------------------------------------ +body SrcWin::location {tag linespec} { + global gdb_running gdb_exe_name _files tcl_platform + + # We need to keep track of changes to the line, filename, function name + # and address so we can keep the widgets up-to-date. Otherwise we + # basically pass things through to the SrcTextWin location public method. + + debug "running=$gdb_running tag=$tag linespec=$linespec" + lassign $linespec foo funcname name line addr pc_addr lib + + # need to call this to update running state + set_execution_status $line $addr + + # "update" doesn't set the tag so we do it here + if {$tag == ""} { + if {$addr == $pc_addr} { + set tag PC_TAG + } else { + set tag STACK_TAG + } + } + + if {!$gdb_running} { + # When we are not yet debugging, we need to force something + # to be displayed, so we choose to find function "main" and + # display the file with it. + set tag BROWSE_TAG + debug "not running: name=$name funcname=$funcname line=$line" + if {$name == ""} { + if {[set linespec [gdbtk_locate_main]] == ""} { + # no "main" function found + return + } + lassign $linespec foo funcname name line addr pc_addr lib + debug "new linespec=$linespec" + } + } + + # update file and function combobox + if {$name != $current(filename)} { + _set_name $name + fillFuncCB $name + } + + # set address and line widgets + $_toolbar configure -address $addr -line $line + + # set function combobox + $_statbar.func entryset $funcname + + # call SrcTextWin::location + $twin location $tag $name $funcname $line $addr $pc_addr $lib + + set current(filename) $name +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: stack - handle stack commands +# ------------------------------------------------------------------ +body SrcWin::stack {cmd} { + if {$cmd == "bottom"} { + set cmd "frame 0" + } + gdbtk_busy + if {[catch {gdb_cmd "$cmd"} message]} { + dbug E "STACK ERROR: $message" + } + gdbtk_update + gdbtk_idle +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: update - update widget when PC changes +# ------------------------------------------------------------------ +body SrcWin::update {} { + if {[catch {gdb_loc} loc]} { + set_execution_status + } else { + debug "loc=$loc" + # See if name combobox needs filled. + if {$need_files} { + fillNameCB + } + location "" $loc + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: idle - callback for gdbtk_idle +# Called when the target is idle, so enable all buttons. +# ------------------------------------------------------------------ +body SrcWin::idle {} { + $_toolbar configure -runstop normal + enable_ui 1 +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: mode - set mode to SOURCE, ASSEMBLY, MIXED, SRC+ASM +# ------------------------------------------------------------------ +body SrcWin::mode {w new_mode {go 1}} { + gdbtk_busy + $_statbar.mode entryset $new_mode + catch {$twin mode_set $new_mode $go} errorVal + $_toolbar configure -displaymode $new_mode + gdbtk_idle +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: _update_title - update title bar +# ------------------------------------------------------------------ +body SrcWin::_update_title {name} { + set fn [lindex [::file split $name] end] + if {$fn == ""} { + set prefix "" + } else { + set prefix "$fn - " + } + window_name "${prefix}Source Window" $fn +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: busy - disable things when gdb is busy +# ------------------------------------------------------------------ +body SrcWin::busy {} { + global gdb_loaded gdb_target_name +# debug "gdb_loaded=$gdb_loaded, gdb_target_name=$gdb_target_name" + + enable_ui 0 + if {$Running} { + $_toolbar configure -runstop running + if {$gdb_loaded || \ + ([TargetSelection::native_debugging] && $gdb_target_name != "remote")} { + set_status "Program is running." + } + } else { + $_toolbar configure -runstop busy + } +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: _set_name - set the name in the name combobox and in the title +# ------------------------------------------------------------------ +body SrcWin::_set_name { val {found 1} } { + global _files + _update_title $val + if {![info exists _files(short,$val)]} { + if {![info exists _files(full,$val)]} { + # not in our list; just display basename + $_statbar.name entryset [lindex [::file split $val] end] + return + } + } else { + set val $_files(short,$val) + } + if {$found} { + $_statbar.name entryset $val + } else { + $_statbar.name entryset "$val (not found)" + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: set_status - write a message to the status line. +# If "tmp" is set, the status change will not be saved. +# ------------------------------------------------------------------ + +body SrcWin::set_status { {msg ""} {tmp 0} } { + set msg [lindex [split $msg \n] 0] + if {$tmp} { + $_status configure -text $msg + return + } + if {$msg != ""} { + set saved_msg $msg + } + $_status configure -text $saved_msg +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: set_execution_status - write the current execution state +# to the status line +# ------------------------------------------------------------------ +body SrcWin::set_execution_status { {line ""} {pc ""}} { + global gdb_running gdb_loaded gdb_program_has_run gdb_target_changed + #debug "line=$line pc=$pc [gdb_target_has_execution] running=$gdb_running loaded=$gdb_loaded" + set message "" + + if {![gdb_target_has_execution]} { + if {$gdb_running} { + set gdb_running 0 + # tell text window program is no longer running + $twin ClearTags + } + if {$gdb_loaded} { + if {$gdb_program_has_run} { + set message "Program terminated. 'Run' will restart." + # Need to set gdb_target_changed because most + # remote targets detach when they are finished, + # and this will force it to reattach. + set gdb_target_changed 1 + set gdb_running 0 + } else { + set message "Program is ready to run." + } + } else { + set message "Program not running. Click on run icon to start." + } + } else { + + # gdb_target_has_execution has returned true, so we must be running. + # + # This can cause problems on targets which do not set inferior_pid. + # Although this is bogus, much of gdb (and gdbtk) relies on + # gdb_target_has_execution (and thus inferior_pid), so we should + # not try to second guess it and fix those targets which do not set + # inferior_pid when opened. + set gdb_running 1 + + # only do a gdb_loc if we have to + if {$line == "" && $pc == ""} { + if {[catch {gdb_loc} loc] == 0} { + set line [lindex $loc 3] + set pc [lindex $loc 4] + } + } + + if {$line == "" || $line == 0} { + if {$pc == "" || $pc == 0} { + if {$Tracing} { + set message "Ready." + } else { + set message "Program stopped." + } + } else { + set message [gdb_cmd "printf \"Program stopped at %lx\",$pc"] + } + } else { + if {$Tracing} { + set msg "Inspecting trace" + } else { + set msg "Program stopped" + } + switch [$twin mode_get] { + ASSEMBLY {set message [gdb_cmd "printf \"$msg at 0x%lx\",$pc"] } + MIXED {set message [gdb_cmd "printf \"$msg at line $line, 0x%lx\",$pc"] } + SRC+ASM {set message [gb_cmd "printf \"$msg at line $line, 0x%lx\",$pc"] } + default {set message "$msg at line $line" } + } + } + } + set_status $message +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: edit - invoke external editor +# ------------------------------------------------------------------ +body SrcWin::edit {} { + global enable_external_editor external_editor_command + # If external editor is enabled, pass the file to the specified command + + if {$current(filename) == ""} { + tk_dialog .warn {Edit} {No file is loaded in the source window.} error 0 Ok + return + } + + if {[catch {$twin report_source_location} loc_info]} { + tk_dialog .warn "Edit" "No source file selected" error 0 Ok + return + } + + + if {[info exists enable_external_editor] && $enable_external_editor} { + if {[catch {eval $external_editor_command edit $loc_info} err]} { + tk_dialog .warn-sn "Edit" $err error 0 Ok + } + return + } +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: print - print the contents of the text widget +# ------------------------------------------------------------------ +body SrcWin::print {} { + # Call the SrcTextWin's print public method + $twin print $top +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: enable_ui +# Enable all UI elements for user interaction. +# ------------------------------------------------------------------ +body SrcWin::enable_ui { on } { + #debug "$on" + if {$on} { + set Running 0 + set state normal + set glyph "" + } else { + if {!$NoRun} {set Running 1} + set state disabled + set glyph watch + } + # combo boxes + $_statbar.mode configure -state $state + $_statbar.name configure -state $state + $_statbar.func configure -state $state + + $twin enable $on + $top configure -cursor $glyph +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: no_inferior +# Put the UI elements of this object into a state +# appropriate for an inferior which is not executing. +# For this object, this means: +# Disable: +# - key binding for all inferior control (not needed -- gdb does this +# for us) +# +# Enable: +# - file/func/mode selectors +# - right-click popups, since gdb DOES allow looking at exe fil +# - selections +# +# Change mouse pointer to normal +# ------------------------------------------------------------------ +body SrcWin::no_inferior {} { + #debug + set_execution_status + enable_ui 1 +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: reset - reset the source window +# ------------------------------------------------------------------ +body SrcWin::reset {} { + set current(filename) "" + set need_files 1 + set do_updates 1 + set last_section "" + set last_section_start 0 + set last_done 0 + set saved_msg "" + + # do we need to flush the cache or clear the source windows? + + # Empty combo boxes + $_statbar.name list delete 0 end + $_statbar.name configure -value {} + $_statbar.func list delete 0 end + $_statbar.func configure -value {} +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: _search - search for text or jump to a specific line +# in source window, going in the specified DIRECTION. +# ------------------------------------------------------------------ +body SrcWin::_search {direction} { + set exp [$_statbar.frame.search get] + #debug "searching $direction for \"$exp\"" + set_status + set_status [$twin search $exp $direction] 1 +} + +# ------------------------------------------------------------------ +# PROCEDURE: point_to_main +# Proc that may be called to point some source window to +# main (or an entry point?). (see gdbtk_tcl_exec_file_changed) +# ------------------------------------------------------------------ +body SrcWin::point_to_main {} { + # We need to force this to some default location. Assume main and + # if that fails, let the source window guess (via gdb_loc using stop_pc). + set src [lindex [ManagedWin::find SrcWin] 0] + if {[set linespec [gdbtk_locate_main]] == ""} { + gdbtk_update + debug "could not find main" + } else { + $src location BROWSE_TAG [list $linespec] + } +} + +body SrcWin::_exit {} { + debug + if {[llength [ManagedWin::find SrcWin]] == 1} { + if {![gdbtk_quit_check]} { + return + } + } + after idle [delete object $this] +} + +# public method for testing use only! +body SrcWin::test_get {var {private_func 0}} { + debug $var + if {$private_func} { + return [code $this $var] + } + return [set $var] +} + +# ------------------------------------------------------------------ +# PUBLIC METHOD: toolbar - configure the toolbar's "state" +# ------------------------------------------------------------------ +# +# This method is used to configure the toolbar's running state. +# Valid states include anything that the "runtest" variable of +# the GDBSrcBar may accept. Specifically, +# +# busy - Run button becomes disabled +# running - Stop button appears, allowing user to stop executing target +# downloading - Stop button appears, allowing user to interrupt downloading +# normal - Run button appears, allowing user to run/re-run exe +body SrcWin::toolbar {state} { + $_toolbar configure -runstop $state +} + +# ------------------------------------------------------------------ +# METHOD: inferior - change execution state of inferior +# ------------------------------------------------------------------ +# +# ACTION may be: +# step - step the inferior one source line (stepping into functions) +# next - step the inferior one source line (stepping over functions) +# finish - finish the current frame of execution +# continue - continue executing the inferior +# stepi - step one machine instruction (stepping into calls) +# nexti - step one machine instruction (stepping over calls) +# run - run/re-run the inferior +# stop - stop or detach from target +# +# FIXME: This should really be in an object which describes gdb's state. +# Unfortunately, this doesn't exist, so it's here for now. +body SrcWin::inferior {action} { + + switch $action { + step { gdbtk_step } + + next { gdbtk_next } + + finish { gdbtk_finish } + + continue { gdbtk_continue } + + stepi { gdbtk_stepi } + + nexti { gdbtk_nexti } + + run { gdbtk_run } + + stop { gdbtk_stop } + } +} + +# ------------------------------------------------------------------ +# METHOD: clear_file +# Tasks for SrcWin to clear file: +# +# - clear window +# - reset to src mode +# - clear func/file comboboxes +# - clear status (done by no_inferior) +# - allow SrcTextWin to clear_file +# ------------------------------------------------------------------ +body SrcWin::clear_file {} { + + # Reset to Source mode + if {[$twin mode_get] != "SOURCE"} { + mode {} SOURCE + } + + no_inferior + reset + + # run srctextwin clear_file + $twin clear_file +} diff --git a/gdb/gdbtk/library/srcwin.ith b/gdb/gdbtk/library/srcwin.ith new file mode 100644 index 00000000000..f955158d445 --- /dev/null +++ b/gdb/gdbtk/library/srcwin.ith @@ -0,0 +1,88 @@ +# Source window class definition for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements a source display widget using primitive widgets as the +# building blocks. +# +# The main display for SrcWin is a SrcTextWin widget. This file +# should contain all the code for controlling the SrcTextWin. +# SrcTextWin should just display the requested file and lines, without +# having to be very intelligent. If there are problems, error codes +# should be returned and SrcWin should figure out what to do. +# ---------------------------------------------------------------------- + +class SrcWin { + inherit TopLevelWin GDBWin + + public { + method busy {} + method constructor {args} + method destructor {} + method download_progress { section num tot {msg ""} } + method edit {} + method enable_ui { on } + method fillNameCB {} + method fillFuncCB {name} + method goto_func {w {val ""}} + method idle {} + method location {tag linespec} + method mode {w new_mode {go 1}} + method no_inferior {} + method print {} + method reconfig {} + method reset {} + method set_status { {msg ""} {tmp 0} } + method set_execution_status { {line ""} {pc ""}} + method stack {cmd} + method test_get {var {private_func 0}} + method toggle_updates {value} + method update {} + method toolbar {state} + method inferior {action} + method clear_file {} + + proc point_to_main {} + } + + private { + method _build_win {} + method _exit {} + method _name {w {val ""}} + method _search {direction} + method _set_name { val {found 1} } + method _set_state {varname} + method _update_title {name} + variable _statbar + variable _status + variable _toolbar + variable top + variable twin + variable current + variable need_files 0 + variable do_updates 1 ;# if the window does updates + variable _mangled_func + variable Tracing + variable saved_msg "" ;# static + + # statics used for downloads + variable last_section "" + variable last_section_start 0 + variable last_done 0 + + # fenceposts + variable Running 0 + variable NoRun 0 + } +} diff --git a/gdb/gdbtk/library/stackwin.itb b/gdb/gdbtk/library/stackwin.itb new file mode 100644 index 00000000000..58675df3836 --- /dev/null +++ b/gdb/gdbtk/library/stackwin.itb @@ -0,0 +1,176 @@ +# Stack window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new stack window +# ------------------------------------------------------------------ +body StackWin::constructor {args} { + gdbtk_busy + build_win + gdbtk_idle + + add_hook gdb_update_hook [code $this update] + add_hook gdb_busy_hook [code $this busy] + add_hook gdb_no_inferior_hook [code $this no_inferior] + add_hook gdb_idle_hook [code $this idle] +} + +# ------------------------------------------------------------------ +# DESTRUCTOR - destroy window containing widget +# ------------------------------------------------------------------ +body StackWin::destructor {} { + remove_hook gdb_update_hook [code $this update] + remove_hook gdb_idle_hook [code $this idle] + remove_hook gdb_busy_hook [code $this busy] + remove_hook gdb_no_inferior_hook [code $this no_inferior] +} + +# ------------------------------------------------------------------ +# METHOD: build_win - build the main register window +# ------------------------------------------------------------------ +body StackWin::build_win {} { + global tixOption tcl_platform + if {$tcl_platform(platform) == "windows"} { + tixScrolledListBox $itk_interior.s -scrollbar both -sizebox 1 + } else { + tixScrolledListBox $itk_interior.s -scrollbar auto + } + set lb [$itk_interior.s subwidget listbox] + $lb configure -selectmode single -bg $tixOption(input1_bg) \ + -selectbackground [pref get gdb/src/STACK_TAG] \ + -selectforeground black \ + -font src-font \ + -exportselection false + update + $lb configure -width $maxwidth + + # bind mouse button 1 to change the stack frame + bind $lb <ButtonPress-1> [code $this change_frame %y] + bind $lb <ButtonRelease-1> break + + pack $itk_interior.s -side left -expand yes -fill both + + window_name "Stack" +} + + +# ------------------------------------------------------------------ +# METHOD: update - update widget when PC changes +# ------------------------------------------------------------------ +body StackWin::update {} { + global gdb_selected_frame_level + + if {!$protect_me} { + set lb [$itk_interior.s subwidget listbox] + + # The gdb_stack command might fail, for instance if you are browsing + # a trace experiment, and the stack has not been collected. + + if {[catch {gdb_stack 0 -1} frames]} { + dbug W "Error in stack collection $frames" + set frames {} + } + + if {[llength $frames] == 0} { + $lb delete 0 end + $lb insert end {NO STACK} + return + } + + $lb delete 0 end + set levels 0 + foreach frame $frames { + set len [string length $frame] + + if {$len > $maxwidth} { + set maxwidth $len + } + $lb insert end $frame + incr levels + } + + # this next section checks to see if the source + # window is looking at some location other than the + # bottom of the stack. If so, highlight the stack frame + set level [expr {$levels - $gdb_selected_frame_level - 1}] + $lb selection set $level + $lb see $level + } +} + +body StackWin::idle {} { + set Running 0 + cursor {} +} + +# ------------------------------------------------------------------ +# METHOD: change_frame - change the current frame +# This body StackWin::is currently ONLY called from the mouse binding +# ------------------------------------------------------------------ +body StackWin::change_frame {y} { + set lb [$itk_interior.s subwidget listbox] + + if {!$Running && [$lb size] != 0} { + gdbtk_busy + set lb [$itk_interior.s subwidget listbox] + set linenum [$lb nearest $y] + set size [$lb size] + set linenum [expr {$size - $linenum - 1}] + catch {gdb_cmd "frame $linenum"} + + # Run idle hooks and cause all widgets to update + set protect_me 1 + gdbtk_update + set protect_me 0 + gdbtk_idle + } +} + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body StackWin::reconfig {} { + destroy $itk_interior.s + build_win +} + +# ------------------------------------------------------------------ +# METHOD: busy - gdb_busy_hook +# +# This body StackWin::should accomplish blocking +# - clicks in the window +# - change mouse pointer +# ------------------------------------------------------------------ +body StackWin::busy {} { + set Running 1 + cursor watch +} + +# ------------------------------------------------------------------ +# METHOD: no_inferior - gdb_no_inferior_hook +# ------------------------------------------------------------------ +body StackWin::no_inferior {} { + set Running 0 + cursor {} +} + +# ------------------------------------------------------------------ +# METHOD: cursor - set the window cursor +# This is a convenience body StackWin::which simply sets the mouse +# pointer to the given glyph. +# ------------------------------------------------------------------ +body StackWin::cursor {glyph} { + set top [winfo toplevel $itk_interior] + $top configure -cursor $glyph +} diff --git a/gdb/gdbtk/library/stackwin.ith b/gdb/gdbtk/library/stackwin.ith new file mode 100644 index 00000000000..af7132e9e1e --- /dev/null +++ b/gdb/gdbtk/library/stackwin.ith @@ -0,0 +1,42 @@ +# Stack window class definition for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements stack window for gdb +# ---------------------------------------------------------------------- + +class StackWin { + inherit EmbeddedWin GDBWin + + private { + variable maxwidth 40 + variable Running 0 + variable protect_me 0 + method build_win {} + method cursor {glyph} + method change_frame {y} + method update {} + method busy {} + method no_inferior {} + method idle {} + } + + public { + method reconfig {} + method constructor {args} + method destructor {} + } + +} + diff --git a/gdb/gdbtk/library/targetselection.itb b/gdb/gdbtk/library/targetselection.itb new file mode 100644 index 00000000000..f7630872c16 --- /dev/null +++ b/gdb/gdbtk/library/targetselection.itb @@ -0,0 +1,995 @@ +# Target selection dialog for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements GDB TargetSelection dialog +# ---------------------------------------------------------------------- + +# ------------------------------------------------------------------ +# CONSTRUCTOR - create new target selection window +# ------------------------------------------------------------------ +body TargetSelection::constructor {args} { + eval itk_initialize $args + set top [winfo toplevel $itk_interior] + _init + build_win +} + +body TargetSelection::getname {target name} { + + # Init target database if we haven't already done so + init_target_db + + if {[info exists gdb_target($target,$name)]} { + return $gdb_target($target,$name) + } else { + return "" + } +} + +body TargetSelection::init_target_db {} { + # check to see if we already initialized this database + if {$db_inited} { + return + } + set db_inited 1 + + # Target Database + # Set the following members: + # TARGET,pretty-name: Name to display to user + # TARGET,debaud: Default baudrate + # TARGET,baud-rates: Permissible baudrates + # TARGET,cmd: Abstracted command to run for this target (tcpX and com1 are + # replaced with the real port and host/port in set_target) + # TARGET,runlist: List of preferences for the target: {attach download run cont} + # TARGET,after_attaching: a command to run after attaching to the target + + # Default target + set gdb_target(default,pretty-name) "Default" + set gdb_target(default,defbaud) "" + set gdb_target(default,baud-rates) {} + set gdb_target(default,cmd) "" + set gdb_target(default,runlist) {0 0 1 0} + set gdb_target(default,options) "" + set gdb_target(default,after_attaching) {} + + # Exec target + set gdb_target(exec,pretty-name) "Exec" + set gdb_target(exec,defbaud) "" + set gdb_target(exec,baud-rates) {} + set gdb_target(exec,cmd) "" + set gdb_target(exec,runlist) {0 0 1 0} + set gdb_target(exec,options) "" + set gdb_target(exec,after_attaching) {} + + # ADS board w/SDS protocol + set gdb_target(sds,pretty-name) "SDS" + set gdb_target(sds,defbaud) "38400" + set gdb_target(sds,baud-rates) {9600 38400} + set gdb_target(sds,cmd) "sds com1" + set gdb_target(sds,runlist) {1 1 0 1} + set gdb_target(sds,after_attaching) {} + + # Simulator + set gdb_target(sim,pretty-name) "Simulator" + set gdb_target(sim,defbaud) "" + set gdb_target(sim,baud-rates) {} + set gdb_target(sim,cmd) "sim" + set gdb_target(sim,runlist) {1 1 1 0} + set gdb_target(sim,options) "" + set gdb_target(sim,after_attaching) {} + + # Remote + set gdb_target(remote,pretty-name) "Remote/Serial" + set gdb_target(remote,defbaud) "9600" + set gdb_target(remote,baud-rates) {9600 19200 38400 57600} + set gdb_target(remote,cmd) "remote com1" + set gdb_target(remote,runlist) {1 1 0 1} + set gdb_target(remote,after_attaching) {} + set gdb_target(remotetcp,pretty-name) "Remote/TCP" + set gdb_target(remotetcp,defbaud) "TCP" + set gdb_target(remotetcp,baud-rates) {} + set gdb_target(remotetcp,cmd) "remote tcpX" + set gdb_target(remotetcp,runlist) {1 1 0 1} + set gdb_target(remotetcp,after_attaching) {} + + # ARM Angel + set gdb_target(rdi,pretty-name) "ARM Angel/Serial" + set gdb_target(rdi,defbaud) "9600" + set gdb_target(rdi,baud-rates) {9600 19200 38400 57600 115200} + set gdb_target(rdi,cmd) "rdi com1" + set gdb_target(rdi,runlist) {1 1 0 1} + set gdb_target(rdi,after_attaching) {} + + # ARM Angel/Ethernet + set gdb_target(rditcp,pretty-name) "ARM Angel/Ethernet" + set gdb_target(rditcp,defbaud) "ETH" + set gdb_target(rditcp,baud-rates) {} + set gdb_target(rditcp,cmd) "rdi ethX" + set gdb_target(rditcp,runlist) {1 1 0 1} + set gdb_target(rditcp,after_attaching) {} + + # ARM Remote + set gdb_target(rdp,pretty-name) "ARM Remote/Serial" + set gdb_target(rdp,defbaud) "9600" + set gdb_target(rdp,baud-rates) {9600} + set gdb_target(rdp,cmd) "rdp com1" + set gdb_target(rdp,runlist) {1 1 0 1} + set gdb_target(rdp,after_attaching) {} + set gdb_target(rdptcp,pretty-name) "ARM Remote/TCP" + set gdb_target(rdptcp,defbaud) "TCP" + set gdb_target(rdptcp,baud-rates) {} + set gdb_target(rdptcp,cmd) "rdp tcpX" + set gdb_target(rdptcp,runlist) {1 1 0 1} + set gdb_target(rdptcp,after_attaching) {} + + # m32r rev C + set gdb_target(m32r,pretty-name) "M32R/Serial" + set gdb_target(m32r,defbaud) "9600" + set gdb_target(m32r,baud-rates) {9600} + set gdb_target(m32r,cmd) "m32r com1" + set gdb_target(m32r,runlist) {1 1 0 1} + set gdb_target(m32r,after_attaching) {} + set gdb_target(m32rtcp,pretty-name) "M32R/TCP" + set gdb_target(m32rtcp,defbaud) "TCP" + set gdb_target(m32rtcp,baud-rates) {} + set gdb_target(m32rtcp,cmd) "m32r tcpX" + set gdb_target(m32rtcp,runlist) {1 1 0 1} + set gdb_target(m32rtcp,after_attaching) {} + + # m32r msa2000 + set gdb_target(mon2000,pretty-name) "MON2000/Serial" + set gdb_target(mon2000,defbaud) "9600" + set gdb_target(mon2000,baud-rates) {9600} + set gdb_target(mon2000,cmd) "mon2000 com1" + set gdb_target(mon2000,runlist) {1 1 0 1} + set gdb_target(mon2000,after_attaching) {} + set gdb_target(mon2000tcp,pretty-name) "MON2000/TCP" + set gdb_target(mon2000tcp,defbaud) "TCP" + set gdb_target(mon2000tcp,baud-rates) {} + set gdb_target(mon2000tcp,cmd) "mon2000 tcpX" + set gdb_target(mon2000tcp,runlist) {1 1 0 1} + set gdb_target(mon2000tcp,after_attaching) {} + + # sparclite + set gdb_target(sparclite,pretty-name) "SPARClite/Serial" + set gdb_target(sparclite,defbaud) "9600" + set gdb_target(sparclite,baud-rates) {9600} + set gdb_target(sparclite,cmd) "sparclite com1" + set gdb_target(sparclite,runlist) {1 1 0 1} + set gdb_target(sparclite,after_attaching) {} + set gdb_target(sparclitetcp,pretty-name) "SPARClite/TCP" + set gdb_target(sparclitetcp,defbaud) "TCP" + set gdb_target(sparclitetcp,baud-rates) {} + set gdb_target(sparclitetcp,cmd) "sparclite tcpX" + set gdb_target(sparclitetcp,runlist) {1 1 0 1} + set gdb_target(sparclitetcp,after_attaching) {} + + # V850 ICE + set gdb_target(ice,pretty-name) "V850 ICE" + set gdb_target(ice,defbaud) "" + set gdb_target(ice,baud-rates) {} + set gdb_target(ice,cmd) "ice" + set gdb_target(ice,runlist) {1 1 0 1} + set gdb_target(ice,after_attaching) {} + + # MIPS + set gdb_target(mips,pretty-name) "MIPS/Serial" + set gdb_target(mips,defbaud) "9600" + set gdb_target(mips,baud-rates) {9600} + set gdb_target(mips,cmd) "mips com1" + set gdb_target(mips,runlist) {1 1 0 1} + set gdb_target(mips,after_attaching) {} + set gdb_target(mipstcp,pretty-name) "MIPS/TCP" + set gdb_target(mipstcp,defbaud) "TCP" + set gdb_target(mipstcp,baud-rates) {} + set gdb_target(mipstcp,cmd) "mips tcpX" + set gdb_target(mipstcp,runlist) {1 1 0 1} + set gdb_target(mipstcp,after_attaching) {} + + # Picobug + set gdb_target(picobug,pretty-name) "Picobug/Serial" + set gdb_target(picobug,defbaud) "19200" + set gdb_target(picobug,baud-rates) {19200} + set gdb_target(picobug,cmd) "picobug com1" + set gdb_target(picobug,runlist) {1 1 0 1} + set gdb_target(picobug,after_attaching) {} + set gdb_target(picobugtcp,pretty-name) "Picobug/TCP" + set gdb_target(picobugtcp,defbaud) "TCP" + set gdb_target(picobugtcp,baud-rates) {} + set gdb_target(picobugtcp,cmd) "picobug tcpX" + set gdb_target(picobugtcp,runlist) {1 1 0 1} + set gdb_target(picobugtcp,after_attaching) {} + + # Cisco. + set gdb_target(cisco,pretty-name) "Cisco/Serial" + set gdb_target(cisco,defbaud) "38400" + set gdb_target(cisco,baud-rates) {9600 19200 38400 56000} + set gdb_target(cisco,cmd) "cisco com1" + set gdb_target(cisco,runlist) {1 0 0 0} + set gdb_target(cisco,after_attaching) "set os cisco" + set gdb_target(ciscotcp,pretty-name) "Cisco/TCP" + set gdb_target(ciscotcp,defbaud) "TCP" + set gdb_target(ciscotcp,baud-rates) {} + set gdb_target(ciscotcp,cmd) "cisco tcpX" + set gdb_target(ciscotcp,runlist) {1 0 0 0} + set gdb_target(ciscotcp,after_attaching) "set os cisco" +} + +body TargetSelection::default_port {} { + global tcl_platform + switch -regexp $tcl_platform(os) { + Windows { set port com1 } + Linux { set port /dev/ttyS0 } + SunOS { set port /dev/ttya } + AIX { set port /dev/foo1 } + ULTRIX { set port /dev/foo1 } + IRIX { set port /dev/foo1 } + OSF1 { set port /dev/foo1 } + NetBSD { set port /dev/foo1 } + HP-UX { + # Special case... + switch -regexp $tcl_platform(osVersion) { + A.09 { set port /dev/tty00 } + B.10 { set port /dev/tty0p0 } + } + } + default { set port /dev/ttya } + } + + return $port +} + + +body TargetSelection::_init_prefs {} { + + if {$prefs_inited} { + return + } + set prefs_inited 1 + + # these are not target-specific + + pref define gdb/load/main 1 + pref define gdb/load/exit 1 + pref define gdb/load/check 0 + + # these are target-specific + # set up the defaults + pref define gdb/load/default-verbose 0 + pref define gdb/load/default-port [default_port] + pref define gdb/load/default-hostname "" + pref define gdb/load/default-after_attaching {} +} + +body TargetSelection::_init_target {} { + global gdb_target_name + set target_list [get_target_list] + set target $gdb_target_name + + # target = CANCEL should never come into here. If the target was + # returned as CANCEL, it should be fixed by the caller... But it + # should not be harmful if it gets in here. + + if {$target == "" || [string compare $target CANCEL] == 0} { + set target default + } + + set defbaud $gdb_target($target,defbaud) + pref define gdb/load/$target-baud $defbaud + pref define gdb/load/$target-port [pref get gdb/load/default-port] + pref define gdb/load/$target-verbose [pref get gdb/load/default-verbose] + pref define gdb/load/$target-portname 1000 + pref define gdb/load/$target-hostname [pref get gdb/load/default-hostname] + + set err [catch {pref get gdb/load/$target-runlist} run_list] + if {$err} { + set run_list $gdb_target($target,runlist) + pref setd gdb/load/$target-runlist $run_list + } + pref set gdb/src/run_attach [lindex $run_list 0] + pref set gdb/src/run_load [lindex $run_list 1] + pref set gdb/src/run_run [lindex $run_list 2] + pref set gdb/src/run_cont [lindex $run_list 3] + + set err [catch {pref get gdb/load/$target-after_attaching} aa] + if {$err} { + set aa $gdb_target($target,after_attaching) + pref setd gdb/load/$target-after_attaching $aa + } +} + +body TargetSelection::_init {} { + + if {!$trace_inited} { + # Trace all gdb_loaded changes based on target + trace variable gdb_loaded w [code TargetSelection::target_trace] + } + set trace_inited 1 + + init_target_db ;# initialize database + _init_prefs ;# initialize load prefs + _init_target ;# initialize target prefs + set_saved + + # This tells us that the target system is inited. Some of these + # init functions need to be called every time the target dialog is + # posted, some only once. The latter functions can check inited to + # see what they should do. + +} + +# ------------------------------------------------------------------ +# METHOD: build_win - build the dialog +# ------------------------------------------------------------------ +body TargetSelection::build_win {} { + global tcl_platform PREFS_state gdb_ImageDir gdb_target_name + + set f [frame $itk_interior.f] + set opts [frame $itk_interior.moreoptions] + frame $itk_interior.moreoptionsframe + set btns [frame $itk_interior.buttons] + + #labelled frame "Connection" + iwidgets::Labeledframe $f.lab -labelpos nw -labeltext [gettext "Connection"] + set fr [$f.lab childsite] + + # target name + label $fr.tarl -text [gettext "Target:"] + combobox::combobox $fr.tar -editable 0 -command [code $this change_target] \ + -width $Width -maxheight 10 + + # baud rate combobox + label $fr.cbl -text [gettext "Baud Rate:"] + combobox::combobox $fr.cb -editable 0 -command [code $this change_baud] \ + -textvariable [pref varname gdb/load/$target-baud] -width $Width \ + -maxheight 10 + + if {[catch {gdb_cmd "show remotebaud"} res]} { + set baud [pref get gdb/load/$target-baud] + } else { + set baud [lindex $res end] + set baud [string trimright $baud "."] + # When uninitialized, GDB returns a baud rate of 2^32 + # Detect this and ignore it. + if {$baud > 4000000000} { + set baud [pref get gdb/load/$target-baud] + } else { + pref setd gdb/load/$target-baud $baud + } + } + + # host entry widget + entry $fr.host -textvariable [pref varname gdb/load/$target-hostname] \ + -width $Width + + # port combobox + if {$tcl_platform(platform) == "windows"} { + set editable 0 + } else { + set editable 1 + } + + label $fr.portl -text [gettext "Port:"] + combobox::combobox $fr.port -editable $editable \ + -textvariable [pref varname gdb/load/$target-port] \ + -width $Width -maxheight 10 + + # load baud rates into combobox + fill_rates + + # load port combobox + if {$tcl_platform(platform) == "windows"} { + foreach val [port_list] { + $fr.port list insert end $val + } + } else { + # fixme: how do I find valid values for these???? + switch $tcl_platform(os) { + Linux { set ports [list /dev/cua0 /dev/ttyS0 /dev/ttyS1 /dev/ttyS2 /dev/ttyS3]} + SunOS { set ports [list /dev/ttya /dev/ttyb] } + AIX { set ports [list /dev/foo1 /dev/foo2] } + ULTRIX { set ports [list /dev/foo1 /dev/foo2] } + IRIX { set ports [list /dev/foo1 /dev/foo2] } + OSF1 { set ports [list /dev/foo1 /dev/foo2] } + NetBSD { set ports [list /dev/foo1 /dev/foo2] } + HP-UX { + # Special case... + switch -regexp $tcl_platform(osVersion) { + A.09 { set ports [list /dev/tty00 /dev/tty01] } + B.10 { set ports [list /dev/tty0p0 /dev/tty1p0] } + } + } + default { set ports [list UNKNOWN UNKNOWN] } + } + foreach val $ports { + $fr.port list insert end $val + } + } + + # Port entry widget + entry $fr.porte -textvariable [pref varname gdb/load/$target-port] -width $Width + + frame $f.fr + checkbutton $f.fr.main -text [gettext "Set breakpoint at 'main'"] \ + -variable [pref varname gdb/load/main] + checkbutton $f.fr.exit -text [gettext "Set breakpoint at 'exit'"] \ + -variable [pref varname gdb/load/exit] + frame $f.fr.bp + checkbutton $f.fr.bp.at_func -text [gettext "Set breakpoint at"] \ + -variable [pref varname gdb/load/bp_at_func] + entry $f.fr.bp.func -textvariable [pref varname gdb/load/bp_func] -width 20 + checkbutton $f.fr.verb -text [gettext "Display Download Dialog"] \ + -variable [pref varname gdb/load/$target-verbose] + + if {![pref get gdb/control_target]} { + $f.fr.main configure -state disabled + $f.fr.exit configure -state disabled + $f.fr.verb configure -state disabled + $f.fr.bp.at_func configure -state disabled + $f.fr.bp.func configure -state disabled + checkbutton $f.fr.check -text [gettext "Compare to remote executable"] \ + -variable [pref varname gdb/load/check] + if { $gdb_target_name == "exec" } { + $f.fr.check configure -state disabled + } + } + + grid $fr.tarl $fr.tar -sticky w -padx 5 -pady 5 + grid $fr.cbl $fr.cb -sticky w -padx 5 -pady 5 + grid $fr.portl $fr.port -sticky w -padx 5 -pady 5 + set mapped1 $fr.cb + set mapped2 $fr.port + + grid $f.fr.main -sticky w -padx 5 -pady 5 + grid $f.fr.exit -sticky w -padx 5 -pady 5 + pack $f.fr.bp.at_func $f.fr.bp.func -side left + grid $f.fr.bp -sticky w -padx 5 -pady 5 + grid $f.fr.verb -sticky w -padx 5 -pady 5 + if {![pref get gdb/control_target]} { + grid $f.fr.check -sticky w -padx 5 -pady 5 + } + + grid $f.lab $f.fr -sticky w -padx 5 -pady 5 + + # Create the "More Options" thingy + if {[lsearch [image names] _MORE_] == -1} { + image create photo _MORE_ -file [file join $gdb_ImageDir more.gif] + image create photo _LESS_ -file [file join $gdb_ImageDir less.gif] + } + + set MoreButton [button $opts.button -image _MORE_ \ + -relief flat -command [code $this toggle_more_options]] + set MoreLabel [label $opts.lbl -text {More Options}] + frame $opts.frame -relief raised -bd 1 + pack $opts.button $opts.lbl -side left + place $opts.frame -relx 1 -x -10 -rely 0.5 -relwidth 0.73 -height 2 -anchor e + + # Create the (hidden) more options frame + set MoreFrame [iwidgets::Labeledframe $itk_interior.moreoptionsframe.frame \ + -labelpos nw -labeltext {Run Options}] + set frame [$MoreFrame childsite] + + set var [pref varname gdb/src/run_attach] + checkbutton $frame.attach -text {Attach to Target} -variable $var + + set var [pref varname gdb/src/run_load] + checkbutton $frame.load -text {Download Program} -variable $var + + set var [pref varname gdb/src/run_cont] + checkbutton $frame.cont -text {Continue from Last Stop} -variable $var \ + -command [code $this set_run run] + + set var [pref varname gdb/src/run_run] + checkbutton $frame.run -text {Run Program} -variable $var \ + -command [code $this set_run cont] + + # The after attaching command entry + set _after_entry [entry $frame.aftere] + label $frame.afterl -text {Command to issue after attaching:} + grid $frame.attach $frame.run -sticky w + grid $frame.load $frame.cont -sticky w + grid $frame.afterl -sticky we -columnspan 2 + grid $frame.aftere -sticky we -columnspan 2 + grid columnconfigure $frame 0 -weight 1 + grid columnconfigure $frame 1 -weight 1 + + # Map everything onto the screen + # This looks like a possible packing bug -- our topmost frame + # will not resize itself. So, instead, use the topmost frame. + #pack $f $opts $itk_interior.moreoptionsframe -side top -fill x + pack $MoreFrame -fill x -expand yes + pack $f $opts -side top -fill x + + change_target $gdb_target($target,pretty-name) + + button $btns.ok -text [gettext OK] -width 7 -command [code $this save] \ + -default active + button $btns.cancel -text [gettext Cancel] -width 7 \ + -command [code $this cancel] + button $btns.help -text [gettext Help] -width 7 -command [code $this help] \ + -state disabled + standard_button_box $btns + bind $btns.ok <Return> "$btns.ok flash; $btns.ok invoke" + bind $btns.cancel <Return> "$btns.cancel flash; $btns.cancel invoke" + bind $btns.help <Return> "$btns.help flash; $btns.help invoke" + + pack $btns -side bottom -anchor e + focus $btns.ok + + # set up balloon help + balloon register $f.fr.bp.at_func "Set User-Speficied Breakpoints at Run Time" + balloon register $f.fr.bp.func "Enter a List of Functions for Breakpoints" + + window_name "Target Selection" + + if {[valid_target $target]} { + $fr.tar configure -value $gdb_target($target,pretty-name) + } + fill_targets + + +} + +# ------------------------------------------------------------------ +# METHOD: set_saved - set saved values +# ------------------------------------------------------------------ +body TargetSelection::set_saved {} { + set saved_baud [pref get gdb/load/$target-baud] + set saved_port [pref get gdb/load/$target-port] + set saved_main [pref get gdb/load/main] + set saved_exit [pref get gdb/load/exit] + set saved_check [pref get gdb/load/check] + set saved_verb [pref get gdb/load/$target-verbose] + set saved_portname [pref get gdb/load/$target-portname] + set saved_hostname [pref get gdb/load/$target-hostname] + set saved_attach [pref get gdb/src/run_attach] + set saved_load [pref get gdb/src/run_load] + set saved_run [pref get gdb/src/run_run] + set saved_cont [pref get gdb/src/run_cont] + if {[info exists gdb_target($target,options)]} { + if {[catch {pref get gdb/load/$target-opts} saved_options]} { + set saved_options "" + } + } +} + +# ------------------------------------------------------------------ +# METHOD: write_saved - write saved values to preferences +# ------------------------------------------------------------------ +body TargetSelection::write_saved {} { + pref setd gdb/load/$target-baud $saved_baud + pref setd gdb/load/$target-port $saved_port + pref setd gdb/load/main $saved_main + pref setd gdb/load/exit $saved_exit + pref setd gdb/load/check $saved_check + pref setd gdb/load/$target-verbose $saved_verb + pref setd gdb/load/$target-portname $saved_portname + pref setd gdb/load/$target-hostname $saved_hostname + pref setd gdb/load/$target-runlist [list $saved_attach $saved_load $saved_run $saved_cont] + if {[info exists gdb_target($target,options)]} { + pref setd gdb/load/$target-opts $saved_options + } + if {[catch {$_after_entry get} saved_after_attaching]} { + set saved_after_attaching "" + } + pref setd gdb/load/$target-after_attaching $saved_after_attaching +} + +# ------------------------------------------------------------------ +# METHOD: fill_rates - fill baud rate combobox +# ------------------------------------------------------------------ +body TargetSelection::fill_rates {} { + $fr.cb list delete 0 end + + if {$gdb_target($target,baud-rates) != ""} { + foreach val $gdb_target($target,baud-rates) { + $fr.cb list insert end $val + } + } +} + +# ------------------------------------------------------------------ +# METHOD: fill_targets - fill target combobox +# ------------------------------------------------------------------ +body TargetSelection::fill_targets {} { + #[$fr.tar subwidget listbox] delete 0 end + $fr.tar list delete 0 end + + foreach val $target_list { + if {[info exists gdb_target($val,pretty-name)]} { + $fr.tar list insert end $gdb_target($val,pretty-name) + + # Insert TCP target, if it exists + if {[info exists gdb_target(${val}tcp,pretty-name)]} { + $fr.tar list insert end $gdb_target(${val}tcp,pretty-name) + } + } + } +} + +# ------------------------------------------------------------------ +# METHOD: config_dialog - Convenience method to map/unmap/rename +# components onto the screen based on target T. +# ------------------------------------------------------------------ +body TargetSelection::config_dialog {t} { + pref define gdb/load/$t-verbose [pref get gdb/load/verbose] + $f.fr.verb config -variable [pref varname gdb/load/$t-verbose] + # Map the correct entries and comboboxes onto the screen + if {$gdb_target($t,defbaud) == "TCP"} { + # we have a tcp target + # map host and porte + if {$mapped1 != "$fr.host"} { + grid forget $mapped1 + set mapped1 $fr.host + grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5 + } + $fr.cbl configure -text "Hostname:" + $fr.host config -textvariable [pref varname gdb/load/$t-hostname] + + if {$mapped2 != "$fr.porte"} { + grid forget $mapped2 + set mapped2 $fr.porte + grid $mapped2 -row 2 -column 1 -sticky w -padx 5 -pady 5 + } + $fr.portl configure -text {Port:} + $fr.porte config -textvariable [pref varname gdb/load/$t-portname] -fg black + + $mapped1 configure -state normal + $mapped2 configure -state normal + } elseif {$gdb_target($t,defbaud) == "ETH"} { + # we have a udp target + # map host and porte + if {$mapped1 != "$fr.host"} { + grid forget $mapped1 + set mapped1 $fr.host + grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5 + } + $fr.cbl configure -text "Hostname:" + $fr.host config -textvariable [pref varname gdb/load/$t-hostname] + + if {$mapped2 != "$fr.porte"} { + grid forget $mapped2 + } + $fr.portl configure -text {Port: N/A (fixed)} + + $mapped1 configure -state normal + $mapped2 configure -state disabled + } elseif {$gdb_target($t,defbaud) != ""} { + # we have a serial target + # map port and cb + if {$mapped1 != "$fr.cb"} { + grid forget $mapped1 + set mapped1 $fr.cb + grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5 + } + $fr.cbl configure -text "Baud Rate:" + $fr.cb configure -textvariable [pref varname gdb/load/$t-baud] + + if {$mapped2 != "$fr.port"} { + grid forget $mapped2 + set mapped2 $fr.port + grid $mapped2 -row 2 -column 1 -sticky w -padx 5 -pady 5 + } + $fr.portl configure -text {Port:} + $fr.port configure -textvariable [pref varname gdb/load/$t-port] + + $mapped1 configure -state normal + $mapped2 configure -state normal + } else { + # we have a non-remote(-like) target + # disable all (except tar) and check for + # options + $mapped1 configure -state disabled + $mapped2 configure -state disabled + $fr.porte configure -fg gray + + if {[info exists gdb_target($t,options)]} { + if {$mapped1 != "$fr.host"} { + grid forget $mapped1 + set mapped1 $fr.host + grid $mapped1 -row 1 -column 1 -sticky w -padx 5 -pady 5 + } + $mapped1 configure -state normal + $fr.host config -textvariable [pref varname gdb/load/$t-opts] + + # We call options "arguments" for the exec target + # FIXME: this is really overloaded!! + if {$t == "exec"} { + set text "Arguments:" + } else { + set text "Options:" + } + $fr.cbl configure -text $text + } + } +} + +# ------------------------------------------------------------------ +# METHOD: change_target - callback for target combobox +# ------------------------------------------------------------------ +body TargetSelection::change_target {w {name ""}} { + if {$name == ""} {return} + set target [get_target $name] + debug "$target" + set defbaud $gdb_target($target,defbaud) + pref define gdb/load/$target-baud $defbaud + pref define gdb/load/$target-portname 1000 + pref define gdb/load/$target-hostname [pref get gdb/load/default-hostname] + if {$defbaud == ""} { + pref define gdb/load/$target-port "" + } else { + pref define gdb/load/$target-port [pref get gdb/load/default-port] + } + + config_dialog $target + fill_rates + + # Configure the default run options for this target + set err [catch {pref get gdb/load/$target-runlist} run_list] + if {$err} { + set run_list $gdb_target($target,runlist) + pref setd gdb/load/$target-runlist $run_list + } + + pref set gdb/src/run_attach [lindex $run_list 0] + pref set gdb/src/run_load [lindex $run_list 1] + pref set gdb/src/run_run [lindex $run_list 2] + pref set gdb/src/run_cont [lindex $run_list 3] + set_check_button $name + + set err [catch {pref get gdb/load/$target-after_attaching} aa] + if {$err} { + set aa $gdb_target($target,after_attaching) + pref setd gdb/load/$target-after_attaching $aa + } + + $_after_entry delete 0 end + $_after_entry insert 0 $aa + + set_saved + + set changes 0 +} + +# ------------------------------------------------------------------ +# PRIVATE METHOD: change_baud - called when the baud rate is changed. +# If GDB is running, set baud rate in GDB and read it back. +# ------------------------------------------------------------------ +body TargetSelection::change_baud {w {baud ""}} { + if {$baud != ""} { + if {[string compare $baud "TCP"] != 0} { + gdb_cmd "set remotebaud $baud" + if {[catch {gdb_cmd "show remotebaud"} res]} { + set newbaud 0 + } else { + set newbaud [lindex $res end] + set newbaud [string trimright $newbaud "."] + if {$newbaud > 4000000} { + set newbaud 0 + } + } + if {$newbaud != $baud} { + pref set gdb/load/$target-baud $newbaud + } + } + } +} + + +# ------------------------------------------------------------------ +# METHOD: port_list - return a list of valid ports for Windows +# ------------------------------------------------------------------ +body TargetSelection::port_list {} { + set plist "" + # Scan com1 - com8 trying to open each one. + # If permission is denied that means it is in use, + # which is OK because we may be using it or the user + # may be setting up the remote target manually with + # a terminal program. + for {set i 1} {$i < 9} { incr i} { + if {[catch { set fd [::open COM$i: RDWR] } msg]} { + # Failed. Find out why. + if {[string first "permission denied" $msg] != -1} { + # Port is there, but busy right now. That's OK. + lappend plist com$i + } + } else { + # We got it. Now close it and add to list. + close $fd + lappend plist com$i + } + } + return $plist +} + +# ------------------------------------------------------------------ +# METHOD: get_target_list - return a list of targets supported +# by this GDB. Parses the output of "help target" +# ------------------------------------------------------------------ +body TargetSelection::get_target_list {} { + set native [native_debugging] + set names "" + set res [gdb_cmd "help target"] + foreach line [split $res \n] { + if {![string compare [lindex $line 0] "target"]} { + set name [lindex $line 1] + + # For cross debuggers, do not allow the target "exec" + if {$name == "exec" && !$native} { + continue + } + lappend names $name + } + } + return $names +} + +# ------------------------------------------------------------------ +# METHOD: save - save values +# ------------------------------------------------------------------ +body TargetSelection::save {} { + global gdb_target_name + set err [catch { + set_saved + write_saved + set gdb_target_name $target + pref setd gdb/load/target $target + } errtxt] + if {$err} {debug "target: $errtxt"} + if {[valid_target $gdb_target_name]} { + # Dismiss the dialog box + unpost + } else { + tk_messageBox -message "The current target is not valid." + } + +} + + +# ------------------------------------------------------------------ +# METHOD: cancel - restore previous values +# ------------------------------------------------------------------ +body TargetSelection::cancel {} { + global gdb_target_name + catch {gdb_cmd "set remotebaud $saved_baud"} + + $fr.cb configure -value $saved_baud + write_saved + if {$exportcancel} { + set gdb_target_name CANCEL + } + + # Now dismiss the dialog + unpost +} + +# ------------------------------------------------------------------ +# METHOD: set_check_button - enable/disable compare-section command +# ------------------------------------------------------------------ +body TargetSelection::set_check_button {name} { + if {[winfo exists $itk_interior.f.fr.check]} { + if { $name == "exec" } { + $itk_interior.f.fr.check configure -state disabled + } else { + $itk_interior.f.fr.check configure -state normal + } + } +} + +# ------------------------------------------------------------------ +# METHOD: help - launches context sensitive help. +# ------------------------------------------------------------------ +body TargetSelection::help {} { +} + +# ------------------------------------------------------------------ +# METHOD: reconfig - used when preferences change +# ------------------------------------------------------------------ +body TargetSelection::reconfig {} { + # for now, just delete and recreate + destroy $itk_interior.f + build_win +} + +# ------------------------------------------------------------------ +# METHOD: get_target - get the internal name of a target from the +# pretty-name +# ------------------------------------------------------------------ +body TargetSelection::get_target {name} { + set t {} + set list [array get gdb_target *,pretty-name] + set i [lsearch -exact $list $name] + if {$i != -1} { + incr i -1 + set t [lindex [split [lindex $list $i] ,] 0] + } else { + debug "unknown pretty-name \"$name\"" + } + return $t +} + +# ------------------------------------------------------------------ +# METHOD: toggle_more_options -- toggle displaying the More/Fewer +# Options pane +# ------------------------------------------------------------------ +body TargetSelection::toggle_more_options {} { + if {[$MoreLabel cget -text] == "More Options"} { + $MoreLabel configure -text "Fewer Options" + $MoreButton configure -image _LESS_ + # Bug in Tk? The top-most frame does not shrink... + #pack $MoreFrame + pack $itk_interior.moreoptionsframe -after $itk_interior.moreoptions -fill both -padx 5 -pady 5 + } else { + $MoreLabel configure -text "More Options" + $MoreButton configure -image _MORE_ + #pack forget $MoreFrame + pack forget $itk_interior.moreoptionsframe + } +} + +# ------------------------------------------------------------------ +# METHOD: set_run - set the run button. Make sure not both run and +# continue are selected. +# ------------------------------------------------------------------ +body TargetSelection::set_run {check_which} { + global PREFS_state + set var [pref varname gdb/src/run_$check_which] + global $var + if {[set $var]} { + set $var 0 + } +} + +# ------------------------------------------------------------------ +# PROCEDURE: target_trace +# This procedure is used to configure gdb_loaded +# and possible more) whenever the value of gdb_loaded +# is changed based on the current target. +# ------------------------------------------------------------------ +body TargetSelection::target_trace {variable index op} { + global gdb_target_name gdb_loaded + + switch $gdb_target_name { + + exec { + # The exec target is always loaded. + set gdb_loaded 1 + } + } +} + +# Returns 1 if TARGET is a _runnable_ target for this gdb. +body TargetSelection::valid_target {target} { + set err [catch {gdb_cmd "help target $target"}] + if {$target == "exec" && ![native_debugging]} { + set err 1 + } + + if {[regexp "tcp$" $target]} { + # Special case (of course) + regsub tcp$ $target {} foo + return [valid_target $foo] + } + + return [expr {$err == 0}] +} + +# Returns 1 if this is not a cross debugger. +body TargetSelection::native_debugging {} { + global GDBStartup + + set r [string compare $GDBStartup(host_name) $GDBStartup(target_name)] + return [expr {!$r}] +} diff --git a/gdb/gdbtk/library/targetselection.ith b/gdb/gdbtk/library/targetselection.ith new file mode 100644 index 00000000000..654328fccae --- /dev/null +++ b/gdb/gdbtk/library/targetselection.ith @@ -0,0 +1,98 @@ +# Target selection dialog class definition for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class TargetSelection { + inherit ModalDialog ManagedWin + + private { + variable f + variable fr + variable target + variable saved_baud + variable saved_port + variable saved_main + variable saved_exit + variable saved_check + variable saved_verb + variable saved_portname + variable saved_hostname + variable saved_attach + variable saved_load + variable saved_run + variable saved_cont + variable saved_options + variable saved_after_attaching + variable _after_entry + variable changes 0 + variable target_list "" + + common db_inited 0 + common prefs_inited 0 + common trace_inited 0 + + # The Connection frame has three "sections"; the first contains + # a combobox with all the targets. The second can either be + # a combobox listing available baud rates or an entry for specifying + # the hostname of a TCP connection. The actual widget mapped onto the + # screen is saved in MAPPED1. The third section contains either a + # combobox for the serial port or an entry for the portnumber. The + # widget actually mapped onto the screen is saved in MAPPED2. + variable mapped1 + variable mapped2 + + variable Width 20 + variable MoreButton + variable MoreFrame + variable MoreLabel + + proc _init_prefs {} + proc default_port {} + + method build_win {} + method cancel {} + method change_baud {w {baud ""}} + method change_target {w {name ""}} + method config_dialog {t} + method fill_rates {} + method fill_targets {} + method get_target_list {} + method get_target {name} + method help {} + method _init {} + method _init_target {} + method port_list {} + method save {} + method set_check_button {name} + method set_run {check_which} + method set_saved {} + method target_trace {variable index op} + method toggle_more_options {} + method valid_target {target} + method write_saved {} + } + + public { + variable exportcancel 0 + + method constructor {args} + method reconfig {} + + proc native_debugging {} + proc getname {target name} + proc init_target_db {} + } + + protected common gdb_target + +} diff --git a/gdb/gdbtk/library/tclIndex b/gdb/gdbtk/library/tclIndex new file mode 100644 index 00000000000..73ea49ca0ed --- /dev/null +++ b/gdb/gdbtk/library/tclIndex @@ -0,0 +1,538 @@ +# Tcl autoload index file, version 2.0 +# This file is generated by the "auto_mkindex" command +# and sourced to set up indexing information for one or +# more commands. Typically each line is a command that +# sets an element in the auto_index array, where the +# element name is the name of a command and the value is +# a script that loads the command. + +set auto_index(About) [list source [file join $dir about.tcl]] +set auto_index(ActionDlg) [list source [file join $dir actiondlg.tcl]] +set auto_index(gdbtk_tcl_preloop) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_busy) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_update) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_idle) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_quit_check) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_quit) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_cleanup) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_query) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_warning) [list source [file join $dir interface.tcl]] +set auto_index(show_warning) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_ignorable_warning) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_fputs) [list source [file join $dir interface.tcl]] +set auto_index(echo) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_fputs_error) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_flush) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_start_variable_annotation) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_end_variable_annotation) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_breakpoint) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_tracepoint) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_trace_find_hook) [list source [file join $dir interface.tcl]] +set auto_index(gdb_run_readline_command) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_readline_begin) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_readline) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_readline_end) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_busy) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_idle) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_tstart) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_tstop) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_display) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_register_changed) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_memory_changed) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_pre_add_symbol) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_post_add_symbol) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_file_changed) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_tcl_exec_file_display) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_locate_main) [list source [file join $dir interface.tcl]] +set auto_index(set_exe_name) [list source [file join $dir interface.tcl]] +set auto_index(set_exe) [list source [file join $dir interface.tcl]] +set auto_index(_open_file) [list source [file join $dir interface.tcl]] +set auto_index(set_target_name) [list source [file join $dir interface.tcl]] +set auto_index(set_target) [list source [file join $dir interface.tcl]] +set auto_index(run_executable) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_attach_target) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_step) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_next) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_finish) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_continue) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_stepi) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_nexti) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_attached) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_detached) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_stop) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_stop_idle_callback) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_detach) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_run) [list source [file join $dir interface.tcl]] +set auto_index(set_baud) [list source [file join $dir interface.tcl]] +set auto_index(do_state_hook) [list source [file join $dir interface.tcl]] +set auto_index(disconnect) [list source [file join $dir interface.tcl]] +set auto_index(tstart) [list source [file join $dir interface.tcl]] +set auto_index(tstop) [list source [file join $dir interface.tcl]] +set auto_index(source_file) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_signal) [list source [file join $dir interface.tcl]] +set auto_index(gdbtk_clear_file) [list source [file join $dir interface.tcl]] +set auto_index(initialize_gdbtk) [list source [file join $dir interface.tcl]] +set auto_index(LocalsWin) [list source [file join $dir locals.tcl]] +set auto_index(ModalDialog) [list source [file join $dir modal.tcl]] +set auto_index(pref_read) [list source [file join $dir prefs.tcl]] +set auto_index(pref_save) [list source [file join $dir prefs.tcl]] +set auto_index(escape_value) [list source [file join $dir prefs.tcl]] +set auto_index(unescape_value) [list source [file join $dir prefs.tcl]] +set auto_index(pref_set_defaults) [list source [file join $dir prefs.tcl]] +set auto_index(pref_src-font_trace) [list source [file join $dir prefs.tcl]] +set auto_index(GDBSrcBar) [list source [file join $dir srcbar.tcl]] +set auto_index(TdumpWin) [list source [file join $dir tdump.tcl]] +set auto_index(TfindArgs) [list source [file join $dir tfind_args.tcl]] +set auto_index(GDBToolBar) [list source [file join $dir toolbar.tcl]] +set auto_index(TraceDlg) [list source [file join $dir tracedlg.tcl]] +set auto_index(gdb_add_tracepoint) [list source [file join $dir tracedlg.tcl]] +set auto_index(gdb_edit_tracepoint) [list source [file join $dir tracedlg.tcl]] +set auto_index(keep_raised) [list source [file join $dir util.tcl]] +set auto_index(sleep) [list source [file join $dir util.tcl]] +set auto_index(auto_step) [list source [file join $dir util.tcl]] +set auto_index(auto_step_cancel) [list source [file join $dir util.tcl]] +set auto_index(tfind_cmd) [list source [file join $dir util.tcl]] +set auto_index(save_trace_commands) [list source [file join $dir util.tcl]] +set auto_index(do_test) [list source [file join $dir util.tcl]] +set auto_index(gdbtk_read_defs) [list source [file join $dir util.tcl]] +set auto_index(bp_exists) [list source [file join $dir util.tcl]] +set auto_index(CygScrolledListbox) [list source [file join $dir util.tcl]] +set auto_index(gridCGet) [list source [file join $dir util.tcl]] +set auto_index(find_iwidgets_library) [list source [file join $dir util.tcl]] +set auto_index(get_disassembly_flavor) [list source [file join $dir util.tcl]] +set auto_index(list_disassembly_flavors) [list source [file join $dir util.tcl]] +set auto_index(init_disassembly_flavor) [list source [file join $dir util.tcl]] +set auto_index(list_element_strcmp) [list source [file join $dir util.tcl]] +set auto_index(VariableWin) [list source [file join $dir variables.tcl]] +set auto_index(::VariableWin::getLocals) [list source [file join $dir variables.tcl]] +set auto_index(WarningDlg) [list source [file join $dir warning.tcl]] +set auto_index(::WarningDlg::constructor) [list source [file join $dir warning.tcl]] +set auto_index(WatchWin) [list source [file join $dir watch.tcl]] +set auto_index(AttachDlg) [list source [file join $dir attachdlg.ith]] +set auto_index(Block) [list source [file join $dir blockframe.ith]] +set auto_index(Frame) [list source [file join $dir blockframe.ith]] +set auto_index(BpWin) [list source [file join $dir bpwin.ith]] +set auto_index(BrowserWin) [list source [file join $dir browserwin.ith]] +set auto_index(::BrowserWin::dont_remember_size) [list source [file join $dir browserwin.ith]] +set auto_index(Console) [list source [file join $dir console.ith]] +set auto_index(Stack) [list source [file join $dir data.ith]] +set auto_index(Queue) [list source [file join $dir data.ith]] +set auto_index(DebugWin) [list source [file join $dir debugwin.ith]] +set auto_index(DebugWinDOpts) [list source [file join $dir debugwin.ith]] +set auto_index(Download) [list source [file join $dir download.ith]] +set auto_index(EmbeddedWin) [list source [file join $dir embeddedwin.ith]] +set auto_index(GDBWin) [list source [file join $dir gdbwin.ith]] +set auto_index(GlobalPref) [list source [file join $dir globalpref.ith]] +set auto_index(HtmlViewer) [list source [file join $dir helpviewer.ith]] +set auto_index(PageStack) [list source [file join $dir helpviewer.ith]] +set auto_index(KodWin) [list source [file join $dir kod.ith]] +set auto_index(ManagedWin) [list source [file join $dir managedwin.ith]] +set auto_index(MemPref) [list source [file join $dir mempref.ith]] +set auto_index(MemWin) [list source [file join $dir memwin.ith]] +set auto_index(ProcessWin) [list source [file join $dir process.ith]] +set auto_index(RegWin) [list source [file join $dir regwin.ith]] +set auto_index(SrcPref) [list source [file join $dir srcpref.ith]] +set auto_index(SrcTextWin) [list source [file join $dir srctextwin.ith]] +set auto_index(SrcWin) [list source [file join $dir srcwin.ith]] +set auto_index(StackWin) [list source [file join $dir stackwin.ith]] +set auto_index(TargetSelection) [list source [file join $dir targetselection.ith]] +set auto_index(TopLevelWin) [list source [file join $dir toplevelwin.ith]] +set auto_index(::AttachDlg::constructor) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::build_win) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::doit) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::cancel) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::choose_symbol_file) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::list_pids) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::select_pid) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::clear_pid_selection) [list source [file join $dir attachdlg.itb]] +set auto_index(::AttachDlg::filter_pid_selection) [list source [file join $dir attachdlg.itb]] +set auto_index(::Block::constructor) [list source [file join $dir blockframe.itb]] +set auto_index(::Block::destructor) [list source [file join $dir blockframe.itb]] +set auto_index(::Block::variables) [list source [file join $dir blockframe.itb]] +set auto_index(::Block::_findVariables) [list source [file join $dir blockframe.itb]] +set auto_index(::Block::update) [list source [file join $dir blockframe.itb]] +set auto_index(::Block::info) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::constructor) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::destructor) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::_removeBlock) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::_addBlock) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::_createBlocks) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::update) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::variables) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::new) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::deleteOld) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::_oldBlocks) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::old) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::_findBlock) [list source [file join $dir blockframe.itb]] +set auto_index(::Frame::_findBlockIndex) [list source [file join $dir blockframe.itb]] +set auto_index(::BpWin::constructor) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::destructor) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::build_win) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_add) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_store) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_restore) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_select) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_modify) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_able) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_remove) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_type) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_delete) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::update) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::bp_all) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::get_actions) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::toggle_threads) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::reconfig) [list source [file join $dir bpwin.itb]] +set auto_index(::BpWin::goto_bp) [list source [file join $dir bpwin.itb]] +set auto_index(::BrowserWin::constructor) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::destructor) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_build_win) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_filter_trace_proc) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_filter_trace_after) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_search_src) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::search) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_toggle_more) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_bind_toplevel) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_do_resize) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_resize) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_process_file_selection) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_process_func_selection) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::do_all_bp) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_toggle_bp) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_select) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_set_filter_mode) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_file_hide_h) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_fill_source) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::mode) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_goto_func) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_fill_file_box) [list source [file join $dir browserwin.itb]] +set auto_index(::BrowserWin::_fill_funcs_combo) [list source [file join $dir browserwin.itb]] +set auto_index(::Console::constructor) [list source [file join $dir console.itb]] +set auto_index(::Console::destructor) [list source [file join $dir console.itb]] +set auto_index(::Console::_build_win) [list source [file join $dir console.itb]] +set auto_index(::Console::idle) [list source [file join $dir console.itb]] +set auto_index(::Console::busy) [list source [file join $dir console.itb]] +set auto_index(::Console::insert) [list source [file join $dir console.itb]] +set auto_index(::Console::einsert) [list source [file join $dir console.itb]] +set auto_index(::Console::_previous) [list source [file join $dir console.itb]] +set auto_index(::Console::_search_history) [list source [file join $dir console.itb]] +set auto_index(::Console::_rsearch_history) [list source [file join $dir console.itb]] +set auto_index(::Console::_next) [list source [file join $dir console.itb]] +set auto_index(::Console::_last) [list source [file join $dir console.itb]] +set auto_index(::Console::_first) [list source [file join $dir console.itb]] +set auto_index(::Console::_setprompt) [list source [file join $dir console.itb]] +set auto_index(::Console::activate) [list source [file join $dir console.itb]] +set auto_index(::Console::invoke) [list source [file join $dir console.itb]] +set auto_index(::Console::_delete) [list source [file join $dir console.itb]] +set auto_index(::Console::_insertion) [list source [file join $dir console.itb]] +set auto_index(::Console::_paste) [list source [file join $dir console.itb]] +set auto_index(::Console::get_text) [list source [file join $dir console.itb]] +set auto_index(::Console::_find_lcp) [list source [file join $dir console.itb]] +set auto_index(::Console::_find_completion) [list source [file join $dir console.itb]] +set auto_index(::Console::_complete) [list source [file join $dir console.itb]] +set auto_index(::Console::_reset_tab) [list source [file join $dir console.itb]] +set auto_index(::Stack::constructor) [list source [file join $dir data.itb]] +set auto_index(::Stack::push) [list source [file join $dir data.itb]] +set auto_index(::Stack::destructor) [list source [file join $dir data.itb]] +set auto_index(::Stack::pop) [list source [file join $dir data.itb]] +set auto_index(::Queue::constructor) [list source [file join $dir data.itb]] +set auto_index(::Queue::destructor) [list source [file join $dir data.itb]] +set auto_index(::Queue::pop) [list source [file join $dir data.itb]] +set auto_index(::DebugWin::constructor) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::destructor) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::build_win) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::puts) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::put_trace) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::loadlog) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::_source_all) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::_clear) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::_mark_old) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWin::_save_contents) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWinDOpts::constructor) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWinDOpts::destructor) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWinDOpts::build_win) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWinDOpts::_all) [list source [file join $dir debugwin.itb]] +set auto_index(::DebugWinDOpts::_apply) [list source [file join $dir debugwin.itb]] +set auto_index(::Download::constructor) [list source [file join $dir download.itb]] +set auto_index(::Download::update_download) [list source [file join $dir download.itb]] +set auto_index(::Download::done) [list source [file join $dir download.itb]] +set auto_index(::Download::cancel) [list source [file join $dir download.itb]] +set auto_index(::Download::destructor) [list source [file join $dir download.itb]] +set auto_index(::Download::do_download_hooks) [list source [file join $dir download.itb]] +set auto_index(::Download::download_hash) [list source [file join $dir download.itb]] +set auto_index(::Download::download_it) [list source [file join $dir download.itb]] +set auto_index(::GlobalPref::_init) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::constructor) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::destructor) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::build_win) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::make_font_item) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::resize_font_item_height) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::change_icons) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::wfont_changed) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::font_changed) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::toggle_tracing_mode) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::toggle_tracing) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::ok) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::apply) [list source [file join $dir globalpref.itb]] +set auto_index(::GlobalPref::cancel) [list source [file join $dir globalpref.itb]] +set auto_index(::HtmlViewer::constructor) [list source [file join $dir helpviewer.itb]] +set auto_index(::HtmlViewer::_buildwin) [list source [file join $dir helpviewer.itb]] +set auto_index(::PageStack::push) [list source [file join $dir helpviewer.itb]] +set auto_index(::PageStack::back) [list source [file join $dir helpviewer.itb]] +set auto_index(::PageStack::next) [list source [file join $dir helpviewer.itb]] +set auto_index(::PageStack::more) [list source [file join $dir helpviewer.itb]] +set auto_index(::PageStack::less) [list source [file join $dir helpviewer.itb]] +set auto_index(::PageStack::current) [list source [file join $dir helpviewer.itb]] +set auto_index(::HtmlViewer::_enable) [list source [file join $dir helpviewer.itb]] +set auto_index(::HtmlViewer::back) [list source [file join $dir helpviewer.itb]] +set auto_index(::HtmlViewer::forward) [list source [file join $dir helpviewer.itb]] +set auto_index(::HtmlViewer::link) [list source [file join $dir helpviewer.itb]] +set auto_index(::HtmlViewer::load) [list source [file join $dir helpviewer.itb]] +set auto_index(::HtmlViewer::open_help) [list source [file join $dir helpviewer.itb]] +set auto_index(::KodWin::constructor) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::build_win) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::update) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::display) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::display_list) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::display_object) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::clear) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::top) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::up) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::destructor) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::set_os) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::reconfig) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::busy) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::idle) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::cursor) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::_disable_buttons) [list source [file join $dir kod.itb]] +set auto_index(::KodWin::_restore_buttons) [list source [file join $dir kod.itb]] +set auto_index(::ManagedWin::reconfig) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::window_name) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::reveal) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::restart) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::open_dlg) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::open) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::_open) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::_create) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::find) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::enable) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::init) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::destroy_toplevel) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::freeze_me) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::thaw_me) [list source [file join $dir managedwin.itb]] +set auto_index(::ManagedWin::make_icon_window) [list source [file join $dir managedwin.itb]] +set auto_index(::MemPref::constructor) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::destructor) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::build_win) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::busy) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::idle) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::ok) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::cancel) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::check_numbytes) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::set_bytes_per_row) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::toggle_size_control) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::apply) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::enable_format) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::disable_format) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::pick) [list source [file join $dir mempref.itb]] +set auto_index(::MemPref::reconfig) [list source [file join $dir mempref.itb]] +set auto_index(::MemWin::constructor) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::destructor) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::build_win) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::paste) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::validate) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::create_prefs) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::changed_cell) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::edit) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::toggle_enabled) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::update) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::idle) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::busy) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::newsize) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::update_address_cb) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::update_address) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::BadExpr) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::incr_addr) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::update_addr) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::hidemb) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::reconfig) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::do_popup) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::goto) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::init_addr_exp) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::cursor) [list source [file join $dir memwin.itb]] +set auto_index(::MemWin::memMoveCell) [list source [file join $dir memwin.itb]] +set auto_index(::ProcessWin::constructor) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::build_win) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::update) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::change_context) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::destructor) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::reconfig) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::busy) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::idle) [list source [file join $dir process.itb]] +set auto_index(::ProcessWin::cursor) [list source [file join $dir process.itb]] +set auto_index(::RegWin::constructor) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::destructor) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::build_win) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::init_reg_display_vars) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::handle_set_hook) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::disassembly_changed) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::save_reg_display_vars) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::reg_select_up) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::reg_select_down) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::reg_select_right) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::reg_select_left) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::reg_select) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::dimensions) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::fixLength) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::but3) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::display_all) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::delete_from_display_list) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::edit) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::acceptEdit) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::unedit) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::update) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::idle) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::reconfig) [list source [file join $dir regwin.itb]] +set auto_index(::RegWin::busy) [list source [file join $dir regwin.itb]] +set auto_index(::SrcPref::constructor) [list source [file join $dir srcpref.itb]] +set auto_index(::SrcPref::build_win) [list source [file join $dir srcpref.itb]] +set auto_index(::SrcPref::_apply) [list source [file join $dir srcpref.itb]] +set auto_index(::SrcPref::_cancel) [list source [file join $dir srcpref.itb]] +set auto_index(::SrcPref::_save) [list source [file join $dir srcpref.itb]] +set auto_index(::SrcPref::set_flavor) [list source [file join $dir srcpref.itb]] +set auto_index(::SrcPref::_pick) [list source [file join $dir srcpref.itb]] +set auto_index(::SrcTextWin::constructor) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::destructor) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::trace_find_hook) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::set_control_mode) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::build_popups) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::build_win) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::SetRunningState) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::enable) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::makeBreakDot) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::setTabs) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::enable_disable_src_tags) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::config_win) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::addPopup) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::handle_set_hook) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::disassembly_changed) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::reconfig) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::updateBalloon) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::balloon_value) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::ClearTags) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::_mtime_changed) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::FillSource) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::FillAssembly) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::FillMixed) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::location) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::LoadFile) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::display_line) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::display_breaks) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::insertBreakTag) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::removeBreakTag) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::bp) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::do_bp) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::hasBP) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::hasTP) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::report_source_location) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::lookup_line) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::continue_to_here) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::set_bp_at_line) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::remove_bp_at_line) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::set_tp_at_line) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::next_hit_at_line) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::remove_tp_at_line) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::do_tag_popup) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::do_source_popup) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::addToWatch) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::do_key) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::mode_get) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::mode_set) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::cancelMotion) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::motion) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::showBPBalloon) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::showBalloon) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::getVariable) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::trace_help) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::line_is_executable) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::tracepoint_range) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::search) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::LoadFromCache) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::UnLoadFromCache) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::print) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::ask_thread_bp) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::do_thread_bp) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::test_get) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::clear_file) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::_initialize_srctextwin) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcTextWin::_clear_cache) [list source [file join $dir srctextwin.itb]] +set auto_index(::SrcWin::constructor) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::destructor) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::_build_win) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::_set_state) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::download_progress) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::reconfig) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::_name) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::toggle_updates) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::goto_func) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::fillNameCB) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::fillFuncCB) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::location) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::stack) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::update) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::idle) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::mode) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::_update_title) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::busy) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::_set_name) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::set_status) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::set_execution_status) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::edit) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::print) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::enable_ui) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::no_inferior) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::reset) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::_search) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::point_to_main) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::_exit) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::test_get) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::toolbar) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::inferior) [list source [file join $dir srcwin.itb]] +set auto_index(::SrcWin::clear_file) [list source [file join $dir srcwin.itb]] +set auto_index(::StackWin::constructor) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::destructor) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::build_win) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::update) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::idle) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::change_frame) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::reconfig) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::busy) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::no_inferior) [list source [file join $dir stackwin.itb]] +set auto_index(::StackWin::cursor) [list source [file join $dir stackwin.itb]] +set auto_index(::TargetSelection::constructor) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::getname) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::init_target_db) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::default_port) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::_init_prefs) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::_init_target) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::_init) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::build_win) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::set_saved) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::write_saved) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::fill_rates) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::fill_targets) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::config_dialog) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::change_target) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::change_baud) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::port_list) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::get_target_list) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::save) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::cancel) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::set_check_button) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::help) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::reconfig) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::get_target) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::toggle_more_options) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::set_run) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::target_trace) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::valid_target) [list source [file join $dir targetselection.itb]] +set auto_index(::TargetSelection::native_debugging) [list source [file join $dir targetselection.itb]] diff --git a/gdb/gdbtk/library/tdump.tcl b/gdb/gdbtk/library/tdump.tcl new file mode 100644 index 00000000000..94c1310457c --- /dev/null +++ b/gdb/gdbtk/library/tdump.tcl @@ -0,0 +1,125 @@ +# Trace dump window for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements Tdump window for gdb +# +# PUBLIC ATTRIBUTES: +# +# +# METHODS: +# +# reconfig ....... called when preferences change +# +# +# X11 OPTION DATABASE ATTRIBUTES +# +# +# ---------------------------------------------------------------------- + +itcl_class TdumpWin { + # ------------------------------------------------------------------ + # CONSTRUCTOR - create new tdump window + # ------------------------------------------------------------------ + constructor {config} { + # + # Create a window with the same name as this object + # + set class [$this info class] + set hull [namespace tail $this] + set old_name $this + ::rename $this $this-tmp- + ::frame $hull -class $class + ::rename $hull $old_name-win- + ::rename $this $old_name + + set top [winfo toplevel [namespace tail $this]] + wm withdraw $top + + build_win + add_hook gdb_update_hook "$this update" + after idle [list wm deiconify $top] + + } + + + # ------------------------------------------------------------------ + # METHOD: build_win - build the main tdump window + # ------------------------------------------------------------------ + method build_win {} { + + tixScrolledText [namespace tail $this].stext -scrollbar y -height 200 -width 500 + set twin [[namespace tail $this].stext subwidget text] + + # make window non editable + $twin configure -insertwidth 0 + + pack append [namespace tail $this] [namespace tail $this].stext {left expand fill} + update + } + + + # ------------------------------------------------------------------ + # METHOD: update - update widget when PC changes + # ------------------------------------------------------------------ + method update {} { + #debug "tdump: update" + gdbtk_busy + set tframe_num [gdb_get_trace_frame_num] + + if { $tframe_num!=-1 } { + debug "doing tdump" + $twin delete 1.0 end + + if {[catch {gdb_cmd "tdump $tframe_num" 0} tdump_output]} { + tk_messageBox -title "Error" -message $tdump_output -icon error \ + -type ok + } else { + #debug "tdum output is $tdump_output" + + $twin insert end $tdump_output + $twin see insert + } + } + gdbtk_idle + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - destroy window containing widget + # ------------------------------------------------------------------ + destructor { + remove_hook gdb_update_hook "$this update" + set top [winfo toplevel [namespace tail $this]] + destroy $this + destroy $top + } + + # ------------------------------------------------------------------ + # METHOD: config - used to change public attributes + # ------------------------------------------------------------------ + method config {config} {} + + # ------------------------------------------------------------------ + # METHOD: reconfig - used when preferences change + # ------------------------------------------------------------------ + method reconfig {} { + } + + # + # PROTECTED DATA + # + protected maxwidth 0 + protected twin +} + diff --git a/gdb/gdbtk/library/tfind_args.tcl b/gdb/gdbtk/library/tfind_args.tcl new file mode 100644 index 00000000000..d90447a65a2 --- /dev/null +++ b/gdb/gdbtk/library/tfind_args.tcl @@ -0,0 +1,139 @@ +# TfindArgs +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements tfind arguments dialogs +# +# PUBLIC ATTRIBUTES: +# +# Type .........Type of dialog (tfind pc, tfind line, tfind tracepoint) +# +# config ....... used to change public attributes +# +# PRIVATE METHODS +# +# X11 OPTION DATABASE ATTRIBUTES +# +# +# ---------------------------------------------------------------------- + +itcl_class TfindArgs { + # ------------------------------------------------------------------ + # CONSTRUCTOR - create new tfind arguments dialog + # ------------------------------------------------------------------ + constructor {config} { + # + # Create a window with the same name as this object + # + set class [$this info class] + set hull [namespace tail $this] + set old_name $this + ::rename $this $this-tmp- + ::frame $hull -class $class + ::rename $hull $old_name-win- + ::rename $this $old_name + build_win + } + + # ------------------------------------------------------------------ + # METHOD: build_win - build the dialog + # ------------------------------------------------------------------ + method build_win {} { + + frame $hull.f + frame $hull.f.a + frame $hull.f.b + set f $hull.f.a + + switch $Type { + LN { + set text "Enter argument: " + } + PC { + set text "Enter PC value: " + } + TP { + set text "Enter Tracepoint No.: " + } + FR { + set text "Enter Frame No.:" + } + + if {[string compare $Type $last_type]} != 0} { + global argument + set argument "" + } + + set last_type $Type + + label $f.1 -text $text + entry $f.2 -textvariable argument -width 10 + $f.2 selection range 0 end + grid $f.1 $f.2 -padx 4 -pady 4 -sticky nwe + + button $hull.f.b.ok -text OK -command "$this ok" -width 7 -default active + button $hull.f.b.quit -text Cancel -command "delete object $this" -width 7 + grid $hull.f.b.ok $hull.f.b.quit -padx 4 -pady 4 -sticky ews + + pack $hull.f.a $hull.f.b + grid $hull.f + + focus $f.2 + bind $f.2 <Return> "$this.f.b.ok flash; $this.f.b.ok invoke" + + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - destroy window containing widget + # ------------------------------------------------------------------ + destructor { + set top [winfo toplevel $hull] + manage delete $this 1 + destroy $this + destroy $top + } + + + + # ------------------------------------------------------------------ + # METHOD: ok - do it and quit + # ------------------------------------------------------------------ + method ok {} { + do_it + delete + } + + + # ------------------------------------------------------------------ + # METHOD: do_it - call the gdb command + # ------------------------------------------------------------------ + method do_it {} { + global argument + + + switch $Type { + LN { tfind_cmd "tfind line $argument"} + PC { tfind_cmd "tfind pc $argument"} + TP { tfind_cmd "tfind tracepoint $argument"} + FR { tfind_cmd "tfind $argument"} + } + } + + + public Type + common last_type {} + private hull + + +} diff --git a/gdb/gdbtk/library/toolbar.tcl b/gdb/gdbtk/library/toolbar.tcl new file mode 100644 index 00000000000..592058907b2 --- /dev/null +++ b/gdb/gdbtk/library/toolbar.tcl @@ -0,0 +1,845 @@ +# Menu, toolbar, and status window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# Implements a menu, toolbar, and status window for GDB +# This class has methods for adding buttons & menus, and +# a collection of methods for the standard GDB menu sets +# and button sets. It does not actually add any buttons or +# menus on its own, however. + +class GDBToolBar { + inherit itk::Widget + + # ------------------------------------------------------------------ + # CONSTRUCTOR - create new console window + # ------------------------------------------------------------------ + constructor {src} { + set source $src + _load_images + _load_src_images + + build_win + add_hook gdb_idle_hook "$this enable_ui 1" + add_hook gdb_busy_hook "$this enable_ui 0" + add_hook gdb_no_inferior_hook "$this enable_ui 2" + add_hook gdb_set_hook "$this set_hook" + } + + # ------------------------------------------------------------------ + # METHOD: build_win - build the main toolbar window + # ------------------------------------------------------------------ + public method build_win {} { + + set OtherMenus {} + set ControlMenus {} + set OtherButtons {} + set ControlButtons {} + + set Menu [menu $itk_interior.m -tearoff 0] + if {! [create_menu_items]} { + destroy $Menu + set Menu {} + } else { + [winfo toplevel $itk_interior] configure -menu $Menu + } + + # Make a subframe so that the menu can't accidentally conflict + # with a name created by some subclass. + set ButtonFrame [frame $itk_interior.t] + create_buttons + + if {! [llength $button_list]} { + destroy $ButtonFrame + } else { + eval standard_toolbar $ButtonFrame $button_list + pack $ButtonFrame $itk_interior -fill both -expand true + } + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - destroy window containing widget + # ------------------------------------------------------------------ + destructor { + remove_hook gdb_idle_hook "$this enable_ui 1" + remove_hook gdb_busy_hook "$this enable_ui 0" + remove_hook gdb_no_inferior_hook "$this enable_ui 2" + remove_hook gdb_set_hook "$this set_hook" + #destroy $this + } + + # ------------------------------------------------------------------ + # METHOD: reconfig - used when preferences change + # ------------------------------------------------------------------ + public method reconfig {} { + debug "toolbar::reconfig" + _load_images 1 + } + + public method _set_stepi {} { + } + + # ------------------------------------------------------------------ + # METHOD: create_buttons - Add some buttons to the toolbar. Returns + # list of buttons in form acceptable to + # standard_toolbar. + # ------------------------------------------------------------------ + public method create_buttons {} { + _load_images + create_buttons + } + + method add_label {name text balloon args} { + set lname $ButtonFrame.$name + eval label $lname -text \$text $args + balloon register $lname $balloon + lappend button_list $lname + } + + + # ------------------------------------------------------------------ + # METHOD: create_button - Creates all the bookkeeping for a button, + # without actually inserting it in the toolbar. + # ------------------------------------------------------------------ + method create_button {name class command balloon args} { + set bname $ButtonFrame.$name + set Buttons($name) $bname + + eval button $bname -command \$command $args + balloon register $bname $balloon + foreach elem $class { + switch $elem { + None {} + default { + lappend ${elem}Buttons $bname + } + } + } + + return $bname + } + + # ------------------------------------------------------------------ + # METHOD: add_button - Creates a button, and inserts it at the end + # of the button list. Call this when the toolbar is being + # set up, but has not yet been made. + # ------------------------------------------------------------------ + method add_button {name class command balloon args} { + + lappend button_list [eval create_button \$name \$class \$command \$balloon $args] + + } + + # ------------------------------------------------------------------ + # METHOD: insert_button - Inserts button "name" before button "before". + # the toolbar must be made, and the buttons must have been created + # before you run this. + # ------------------------------------------------------------------ + method insert_button {name before} { + + if {[string first "-" $name] == 0} { + set name [string range $name 1 end] + set add_sep 1 + } else { + set add_sep 0 + } + + if {![info exists Buttons($name)] || ![info exists Buttons($before)]} { + error "insert_buttons called with non-existant button" + } + + set before_col [gridCGet $Buttons($before) -column] + set before_row [gridCGet $Buttons($before) -row] + + set slaves [grid slaves $ButtonFrame] + + set incr [expr 1 + $add_sep] + foreach slave $slaves { + set slave_col [gridCGet $slave -column] + if {$slave_col >= $before_col} { + grid configure $slave -column [expr $slave_col + $incr] + } + } + if {$add_sep} { + grid $Buttons(-$name) -column $before_col -row $before_row + } + + # Now grid our button. Have to put in the pady since this button + # may not have been originally inserted by the libgui toolbar + # proc. + + grid $Buttons($name) -column [expr $before_col + $add_sep] \ + -row $before_row -pady 2 + + } + + method remove_button {name} { + + if {[string first "-" $name] == 0} { + set name [string range $name 1 end] + set remove_sep 1 + } else { + set remove_sep 0 + } + + if {![info exists Buttons($name)] } { + error "remove_buttons called with non-existant button $name" + } + + set name_col [gridCGet $Buttons($name) -column] + set name_row [gridCGet $Buttons($name) -row] + + grid remove $Buttons($name) + if {$remove_sep} { + set Buttons(-$name) [grid slaves $ButtonFrame \ + -column [expr $name_col - 1] \ + -row $name_row] + grid remove $Buttons(-$name) + } + + set slaves [grid slaves $ButtonFrame -row $name_row] + + foreach slave $slaves { + set slave_col [gridCGet $slave -column] + if {$slave_col > $name_col} { + grid configure $slave -column [expr $slave_col - 1] + } + } + } + + method add_button_separator {} { + lappend button_list - + } + + method button_right_justify {} { + lappend button_list -- + } + + method swap_button_lists {in_list out_list} { + # Now swap out the buttons... + set first_out [lindex $out_list 0] + if {[info exists Buttons($first_out)] && [grid info $Buttons($first_out)] != ""} { + foreach button $in_list { + insert_button $button $first_out + } + foreach button $out_list { + remove_button $button + } + } elseif {[info exists Buttons($first_out)]} { + debug "Error in swap_button_list - $first_out not gridded..." + } else { + debug "Button $first_out is not in button list" + } + } + + ############################################################ + # The next set of commands control the menubar associated with the + # toolbar. Currently, only sequential addition of submenu's and menu + # entries is allowed. Here's what you do. First, create a submenu + # with the "new_menu" command. This submenu is the targeted menu. + # Subsequent calls to add_menu_separator, and add_menu_command add + # separators and commands to the end of this submenu. + # If you need to edit a submenu, call clear_menu and then add all the + # items again. + # + # Each menu command also has a class list. Transitions between states + # of gdb will enable and disable different classes of menus. + # + # FIXME - support insert_command, and also cascade menus, whenever + # we need it... + # FIXME - The toolbar and the Menubar support are glommed together in + # one class for historical reasons, but there is no good reason for this. + ############################################################ + + # ------------------------------------------------------------------ + # METHOD: create_menu_items - Add some menu items to the menubar. + # Returns 1 if any items added. + # + # num = number of last menu entry + # ------------------------------------------------------------------ + method create_menu_items {} { + # Empty - This is overridden in child classes. + } + + # ------------------------------------------------------------------ + # METHOD: new_menu - Add a new cascade menu to the Toolbar's main menu. + # Also target this menu for subsequent add_menu_command + # calls. + # + # name - the token for the new menu + # label - The label used for the label + # underline - the index of the underlined character for this menu item. + # + # RETURNS: then item number of the menu. + # ------------------------------------------------------------------ + method new_menu {name label underline} { + set current_menu $Menu.$name + set menu_list($name) [$Menu add cascade -menu $current_menu \ + -label $label -underline $underline] + menu $current_menu -tearoff 0 + + set item_number -1 + return $current_menu + } + + # ------------------------------------------------------------------ + # METHOD: menu_exists - Report whether a menu keyed by NAME exists. + # + # name - the token for the menu sought + # + # RETURNS: 1 if the menu exists, 0 otherwise. + # ------------------------------------------------------------------ + method menu_exists {name} { + return [info exists menu_list($name)] + + } + + # ------------------------------------------------------------------ + # METHOD: clear_menu - Deletes the items from one of the cascade menus + # in the Toolbar's main menu. Also makes this menu + # the target menu. + # + # name - the token for the new menu + # + # RETURNS: then item number of the menu, or "" if the menu is not found. + # ------------------------------------------------------------------ + method clear_menu {name} { + if {[info exists menu_list($name)]} { + set current_menu [$Menu entrycget $menu_list($name) -menu] + $current_menu delete 0 end + set item_number -1 + return $current_menu + } else { + return "" + } + } + + + # ------------------------------------------------------------------ + # METHOD: add_menu_separator - Adds a menu separator to the currently + # targeted submenu of the Toolbar's main menu. + # + # ------------------------------------------------------------------ + method add_menu_separator {} { + incr item_number + $current_menu add separator + } + + # ------------------------------------------------------------------ + # METHOD: add_menu_command - Adds a menu command item to the currently + # targeted submenu of the Toolbar's main menu. + # + # class - The class of the command, used for disabling entries. + # label - The text for the command. + # command - The command for the menu entry + # args - Passed to the menu entry creation command (eval'ed) + # ------------------------------------------------------------------ + method add_menu_command {class label command args} { + + eval $current_menu add command -label \$label -command \$command \ + $args + + incr item_number + + switch $class { + None {} + default { + foreach elem $class { + lappend menu_classes($elem) [list $current_menu $item_number] + } + } + } + } + + + # ------------------------------------------------------------------ + # METHOD: _load_images - Load standard images. Private method. + # ------------------------------------------------------------------ + public method _load_images { {reconfig 0} } { + global gdb_ImageDir + if {!$reconfig && $_loaded_images} { + return + } + set _loaded_images 1 + + lappend imgs console reg stack vmake vars watch memory bp + foreach name $imgs { + image create photo ${name}_img -file [file join $gdb_ImageDir ${name}.gif] + } + } + + + # ------------------------------------------------------------------ + # METHOD: _load_src_images - Load standard images. Private method. + # ------------------------------------------------------------------ + method _load_src_images { {reconf 0} } { + global gdb_ImageDir + + if {!$reconf && $_loaded_src_images} { + return + } + set _loaded_src_images 1 + + foreach name {run stop step next finish continue edit \ + stepi nexti up down bottom Movie_on Movie_off \ + next_line next_check next_hit rewind prev_hit \ + watch_movie run_expt tdump tp} { + image create photo ${name}_img -file [file join $gdb_ImageDir ${name}.gif] + } + } + + # ------------------------------------------------------------------ + # METHOD: enable_ui - enable/disable the appropriate buttons and menus + # Called from the busy, idle, and no_inferior hooks. + # + # on must be: + # value Control Other Trace State + # 0 off off off gdb is busy + # 1 on on off gdb has inferior, and is idle + # 2 off on off gdb has no inferior, and is idle + # ------------------------------------------------------------------ + public method enable_ui {on} { + global tcl_platform + debug "Toolbar::enable_ui $on - Browsing=$Browsing" + + # Do the enabling so that all the disabling happens first, this way if a + # button belongs to two groups, enabling takes precedence, which is probably right. + + switch $on { + 0 { + set enable_list {Control disabled \ + Other disabled \ + Trace disabled \ + Attach disabled \ + Detach disabled} + } + 1 { + if {!$Browsing} { + set enable_list {Trace disabled \ + Control normal \ + Other normal \ + Attach disabled \ + Detach normal } + # set the states of stepi and nexti correctly + _set_stepi + } else { + set enable_list {Control disabled Other normal Trace normal} + } + + } + 2 { + set enable_list {Control disabled \ + Trace disabled \ + Other normal \ + Attach normal \ + Detach disabled } + } + default { + debug "Unknown type: $on in enable_ui" + return + } + } + + debug "Enable list is: $enable_list" + foreach {type state} $enable_list { + if {[info exists ${type}Buttons]} { + foreach button [set ${type}Buttons] { + $button configure -state $state + } + } + if {[info exists menu_classes($type)]} { + change_menu_state $menu_classes($type) $state + } + } + + } + + # ------------------------------------------------------------------ + # METHOD: change_menu_state - Does the actual job of enabling menus... + # Pass normal or disabled for the state. + # ------------------------------------------------------------------ + method change_menu_state {menuList state} { + + foreach elem $menuList { + [lindex $elem 0] entryconfigure [lindex $elem 1] -state $state + } + } + + + # + # The next set of functions are the generic button groups that gdb uses. + # Then toolbars that derive from this class can just mix and match + # from the standard set as they please. + # + + # ------------------------------------------------------------------ + # METHOD: create_control_buttons - Creates the step, continue, etc buttons. + # ------------------------------------------------------------------ + + method create_control_buttons {} { + add_button step Control [code $source inferior step] \ + "Step (S)" -image step_img + + add_button next Control [code $source inferior next] \ + "Next (N)" -image next_img + + add_button finish Control [code $source inferior finish] \ + "Finish (F)" -image finish_img + + add_button continue Control [code $source inferior continue] \ + "Continue (C)" -image continue_img + + # A spacer before the assembly-level items looks good. It helps + # to indicate that these are somehow different. + add_button_separator + + add_button stepi Control [code $source inferior stepi] \ + "Step Asm Inst (S)" -image stepi_img + + add_button nexti Control [code $source inferior nexti] \ + "Next Asm Inst (N)" -image nexti_img + + _set_stepi + + set Run_control_buttons {step next finish continue -stepi nexti} + + } + + # ------------------------------------------------------------------ + # METHOD: create_trace_buttons - Creates the next hit, etc. + # ------------------------------------------------------------------ + + method create_trace_buttons {{show 0}} { + + if {$show} { + set command add_button + } else { + set command create_button + } + + $command tfindstart Trace {tfind_cmd "tfind start"} "First Hit <F>" \ + -image rewind_img + + $command tfind Trace {tfind_cmd tfind} "Next Hit <N>" -image next_hit_img + + $command tfindprev Trace {tfind_cmd "tfind -"} "Previous Hit <P>" \ + -image prev_hit_img + + $command tfindline Trace {tfind_cmd "tfind line"} "Next Line Hit <L>" \ + -image next_line_img + + $command tfindtp Trace { tfind_cmd "tfind tracepoint"} \ + "Next Hit Here <H>" -image next_check_img + + set Trace_control_buttons {tfindstart tfind tfindprev tfindline tfindtp} + + # This is a bit of a hack, but I need to bind the standard_toolbar bindings + # and appearances to these externally, since I am not inserting them in + # the original toolbar... Have to add a method to the libgui toolbar to do this. + + if {!$show} { + foreach name $Trace_control_buttons { + # Make sure the button acts the way we want, not the default Tk + # way. + set button $Buttons($name) + $button configure -takefocus 0 -highlightthickness 0 \ + -relief flat -borderwidth 1 + set index [lsearch -exact [bindtags $button] Button] + bindtags $button [lreplace [bindtags $button] $index $index \ + ToolbarButton] + } + } + } + + + # ------------------------------------------------------------------ + # METHOD: create_window_buttons - Creates the registers, etc, buttons + # ------------------------------------------------------------------ + + method create_window_buttons {} { + add_button reg Other {ManagedWin::open RegWin} "Registers (Ctrl+R)" -image reg_img + + add_button mem Other {ManagedWin::open MemWin} "Memory (Ctrl+M)" -image memory_img + + add_button stack Other {ManagedWin::open StackWin} "Stack (Ctrl+S)" -image stack_img + + add_button watch Other {ManagedWin::open WatchWin} "Watch Expressions (Ctrl+W)" \ + -image watch_img + + add_button vars Other {ManagedWin::open LocalsWin} "Local Variables (Ctrl+L)" \ + -image vars_img + + if {[pref get gdb/control_target]} { + add_button bp Other {ManagedWin::open BpWin} "Breakpoints (Ctrl+B)" -image bp_img + } + + if {[pref get gdb/mode]} { + add_button tp Other {ManagedWin::open BpWin -tracepoints 1} \ + "Tracepoints (Ctrl+T)" -image tp_img + + add_button tdump Trace {ManagedWin::open TdumpWin} "Tdump (Ctrl+D)" -image tdump_img + } + + add_button con Other {ManagedWin::open Console} "Console (Ctrl+N)" \ + -image console_img + } + + # + # The next set of functions create the common menu groupings that + # are used in gdb menus. + # + + + # ------------------------------------------------------------------ + # METHOD: create_view_menu - Creates the standard view menu + # ------------------------------------------------------------------ + + method create_view_menu {} { + new_menu view "View" 0 + + add_menu_command Other "Stack" {ManagedWin::open StackWin} \ + -underline 0 -accelerator "Ctrl+S" + + add_menu_command Other "Registers" {ManagedWin::open RegWin} \ + -underline 0 -accelerator "Ctrl+R" + + add_menu_command Other "Memory" {ManagedWin::open MemWin} \ + -underline 0 -accelerator "Ctrl+M" + + add_menu_command Other "Watch Expressions" {ManagedWin::open WatchWin} \ + -underline 0 -accelerator "Ctrl+W" + add_menu_command Other "Local Variables" {ManagedWin::open LocalsWin} \ + -underline 0 -accelerator "Ctrl+L" + + if {[pref get gdb/control_target]} { + add_menu_command Other "Breakpoints" \ + {ManagedWin::open BpWin -tracepoints 0} \ + -underline 0 -accelerator "Ctrl+B" + } + + if {[pref get gdb/mode]} { + add_menu_command Other "Tracepoints" \ + {ManagedWin::open BpWin -tracepoints 1} \ + -underline 0 -accelerator "Ctrl+T" + add_menu_command Other "Tdump" {ManagedWin::open TdumpWin} \ + -underline 2 -accelerator "Ctrl+U" + + } + + add_menu_command Other "Console" {ManagedWin::open Console} \ + -underline 2 -accelerator "Ctrl+N" + + add_menu_command Other "Function Browser" {ManagedWin::open BrowserWin} \ + -underline 1 -accelerator "Ctrl+F" + add_menu_command Other "Thread List" {ManagedWin::open ProcessWin} \ + -underline 0 -accelerator "Ctrl+H" + if {[info exists ::env(GDBTK_DEBUG)] && $::env(GDBTK_DEBUG)} { + add_menu_separator + add_menu_command Other "Debug Window" {ManagedWin::open DebugWin} \ + -underline 3 -accelerator "Ctrl+U" + } + } + + # ------------------------------------------------------------------ + # METHOD: create_control_menu - Creates the standard control menu + # ------------------------------------------------------------------ + + method create_control_menu {} { + new_menu cntrl "Control" 0 + + add_menu_command Control "Step" [code $source inferior step] \ + -underline 0 -accelerator S + + add_menu_command Control "Next" [code $source inferior next] \ + -underline 0 -accelerator N + + add_menu_command Control "Finish" [code $source inferior finish] \ + -underline 0 -accelerator F + + add_menu_command Control "Continue" \ + [code $source inferior continue] \ + -underline 0 -accelerator C + + add_menu_separator + add_menu_command Control "Step Asm Inst" \ + [code $source inferior stepi] \ + -underline 1 -accelerator S + + add_menu_command Control "Next Asm Inst" \ + [code $source inferior nexti] \ + -underline 1 -accelerator N + + # add_menu_separator + # add_menu_command Other "Automatic Step" auto_step + + } + + # ------------------------------------------------------------------ + # METHOD: create_trace_menu - Creates the standard trace menu + # ------------------------------------------------------------------ + + method create_trace_menu {} { + new_menu trace "Trace" 0 + + add_menu_command Other "Save Trace Commands..." "save_trace_commands" \ + -underline 0 + + add_menu_separator + + add_menu_command Trace "Next Hit" {tfind_cmd tfind} \ + -underline 0 -accelerator N + + add_menu_command Trace "Previous Hit" {tfind_cmd "tfind -"} \ + -underline 0 -accelerator P + + add_menu_command Trace "First Hit" {tfind_cmd "tfind start"} \ + -underline 0 -accelerator F + + add_menu_command Trace "Next Line Hit" {tfind_cmd "tfind line"} \ + -underline 5 -accelerator L + + add_menu_command Trace "Next Hit Here" {tfind_cmd "tfind tracepoint"} \ + -underline 9 -accelerator H + + add_menu_separator + add_menu_command Trace "Tfind Line..." \ + "ManagedWin::open TfindArgs -Type LN" \ + -underline 9 -accelerator E + + add_menu_command Trace "Tfind PC..." \ + "ManagedWin::open TfindArgs -Type PC" \ + -underline 7 -accelerator C + + add_menu_command Trace "Tfind Tracepoint..." \ + "ManagedWin::open TfindArgs -Type TP" \ + -underline 6 -accelerator T + + add_menu_command Trace "Tfind Frame..." \ + "ManagedWin::open TfindArgs -Type FR" \ + -underline 6 -accelerator F + } + + # ------------------------------------------------------------------ + # METHOD: create_help_menu - Creates the standard help menu + # ------------------------------------------------------------------ + method create_help_menu {} { + new_menu help "Help" 0 + add_menu_command Other "Help Topics" {HtmlViewer::open_help index.html} \ + -underline 0 + add_menu_command Other "Cygnus on the Web" \ + {open_url http://www.cygnus.com/gnupro/} -underline 14 + add_menu_separator + add_menu_command Other "About GDB..." {ManagedWin::open About -transient} \ + -underline 0 + } + + # ------------------------------------------------------------------ + # METHOD: set_hook - run when user enters a `set' command. + # ------------------------------------------------------------------ + method set_hook {varname value} { + debug "Got $varname = $value" + if {$varname == "os"} { + set save_menu $current_menu + set current_menu $Menu.view + set title "Kernel Objects" + if {[catch {$current_menu index $title} index]} { + set index none + } + if {$value == ""} { + # No OS, so remove KOD from View menu. + if {$index != "none"} { + $current_menu delete $index + } + } else { + # Add KOD to View menu, but only if it isn't already there. + if {$index == "none"} { + add_menu_command Other $title {ManagedWin::open KodWin} \ + -underline 0 -accelerator "Ctrl+K" + } + } + set current_menu $save_menu + + global gdb_kod_cmd + set gdb_kod_cmd $value + } + } + + # + # PROTECTED DATA + # + + # + # FIXME - Need to break the images into the sets needed for + # each button group, and load them when the button group is + # created. + + # This is set if we've already loaded the standard images. + private common _loaded_images 0 + + # This is set if we've already loaded the standard images. Private + # variable. + private common _loaded_src_images 0 + + # + # PUBLIC DATA + # + + # This is a handle on our parent source window. + protected variable source {} + + public variable Tracing 0 ;# Is tracing enabled for this gdb? + public variable Browsing 0 ;# Are we currently browsing a trace experiment? + public variable Collecting 0 ;# Are we currently collecting a trace experiment? + + # The list of all control buttons (ones which should be disabled when + # not running anything or when inferior is running) + protected variable ControlButtons {} + + # The list of all other buttons (which are disabled when inderior is + # running) + protected variable OtherButtons {} + + # The list of buttons that are enabled when we are in trace browse + # mode... + protected variable TraceButtons {} + + # This is the list of buttons that are being built up + # + private variable button_list {} + + # + # This is an array of buttons names -> Tk Window names + # + + protected variable Buttons + + # The main window's menu + private variable Menu + + #The frame to contain the buttons: + protected variable ButtonFrame + + # This array holds the menu classes. The key is the class name, + # and the value is the list of menus belonging to this class. + + protected variable menu_classes + + # These buttons go in the control area when we are browsing + protected variable Trace_control_buttons + + # And these go in the control area when we are running + protected variable Run_control_buttons + + protected variable item_number -1 + protected variable current_menu {} +} diff --git a/gdb/gdbtk/library/toplevelwin.ith b/gdb/gdbtk/library/toplevelwin.ith new file mode 100644 index 00000000000..2b947d2a7fe --- /dev/null +++ b/gdb/gdbtk/library/toplevelwin.ith @@ -0,0 +1,64 @@ +# TopLevelWin class definition for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +class TopLevelWin { + inherit ManagedWin + + private variable frame "" + + constructor {args} { + debug $itk_interior + + # create a container frame + conFrame $itk_interior.container + pack $itk_interior.container -fill both -expand 1 + + # set up bindings for group iconification/deiconification + # NOT IMPLEMENTED YET + #set top [winfo toplevel [namespace tail $this]] + #bind_for_toplevel_only $top <Unmap> { + # manage_iconify iconify + #} + #bind_for_toplevel_only $top <Map> { + # manage_iconify deiconify + #} + incr numTopWins + } + + public method conFrame {win} { + set frame [cyg::panedwindow $win -height 5i] + return $frame.con + } + + public method conAdd {child args} { + parse_args {{resizable 1}} + $frame add $child -margin 0 -resizable $resizable + return [$frame childsite $child].con + } + + public method sizeWinByChild {child} { + if {[catch {$frame childsite $child} childWin]} { + debug "Could not find child $child" + return + } + set width [winfo reqwidth $childWin] + $frame configure -width $width + + } + + destructor { + debug + incr numTopWins -1 + } +} diff --git a/gdb/gdbtk/library/tracedlg.tcl b/gdb/gdbtk/library/tracedlg.tcl new file mode 100644 index 00000000000..3650f715044 --- /dev/null +++ b/gdb/gdbtk/library/tracedlg.tcl @@ -0,0 +1,809 @@ +# Trace configuration dialog for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ----------------------------------------------------------------- +# Implements the Tracepoint configuration dialog box. This (modal) +# dialog will be called upon to interact with gdb's tracepoint routines +# allowing the user to add/edit tracepoints. Specifically, user can +# specify: +# +# - What data to collect: locals, registers, "all registers", "all locals", +# user-defined (globals) +# - Number of passes which we should collect the data +# - An ignore count after which data will start being collected +# This method will destroy itself when the dialog is released. It returns +# either one if a tracepoint was set/edited successfully or zero if +# the user bails out (cancel or destroy buttons). + +itcl_class TraceDlg { + # ------------------------------------------------------------------ + # CONSTRUCTOR: create new trace dialog + # ------------------------------------------------------------------ + constructor {config} { + # + # Create a window with the same name as this object + # + set class [$this info class] + set hull [namespace tail $this] + set old_name $this + ::rename $this $this-tmp- + ::frame $hull -class $class + ::rename $hull $old_name-win- + ::rename $this $old_name + + set top [winfo toplevel [namespace tail $this]] + wm withdraw $top + build_win $this + after idle [list wm deiconify $top] + after idle [list $this title] +# after idle grab $this + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - destroy window containing widget + # ------------------------------------------------------------------ + destructor { + + # Remove this window and all hooks +# grab release $this + if {$ActionsDlg != ""} { + catch {manage delete $ActionsDlg} + } + set top [winfo toplevel [namespace tail $this]] + destroy $top + destroy $this + } + + # ------------------------------------------------------------------ + # METHOD: build_win - build the Trace dialog box (cache this?) + # ------------------------------------------------------------------ + method build_win {f} { + global _TPassCount + + + # Need to set the title to either "Add Tracepoint" or "Edit Tracepoint", + # depending on the location of the given tracepoint. + # !! Why can I not do this? + + # If we have multiple lines, we "add" if we have any new ones ONLY.. + set nums {} + set lown -1 + set highn -1 + set lowl -1 + set highl 0 + set functions {} + set last_function {} + set display_lines {} + set display_number {} + + # Look at all lines + foreach line $Lines { + set num [gdb_tracepoint_exists "$File:$line"] + if {$num == -1} { + set New 1 + } else { + set Exists 1 + } + + set function [gdb_get_function "$File:$line"] + if {"$last_function" != "$function"} { + lappend functions $function + set last_function $function + } + + if {$lown == -1 && $num != -1} { + set lown $num + } + if {$lowl == -1} { + set lowl $line + } + + lappend Number $num + if {$num > $highn} { + set highn $num + } + if {$num != -1 && $num < $lown} { + set lown $num + } + if {$line > $highl} { + set highl $line + } + if {$line < $lowl} { + set lowl $line + } + } + + # Look at all addresses + foreach addr $Addresses { + set num [gdb_tracepoint_exists "*$addr"] + if {$num == -1} { + set New 1 + } else { + set Exists 1 + } + + set function [gdb_get_function "*$addr"] + if {"$last_function" != "$function"} { + lappend functions $function + set last_function $function + } + + if {$lown == -1 && $num != -1} { + set lown $num + } + if {$lowl == -1} { + set lowl $addr + } + + lappend Number $num + if {$num > $highn} { + set highn $num + } + if {$num != -1 && $num < $lown} { + set lown $num + } + if {$addr > $highl} { + set highl $addr + } + if {$addr < $lowl} { + set lowl $addr + } + } + + if {$Lines != {}} { + if {[llength $Lines] == 1} { + set Number $lown + set display_number [concat $Number] + set display_lines [concat $Lines] + set multiline 0 + } else { + # range of numbers + set display_number "$lown-$highn" + set display_lines "$lowl-$highl" + set multiline 1 + } + } elseif {$Addresses != {}} { + if {[llength $Addresses] == 1} { + set Number $lown + set display_number [concat $Number] + set display_lines [concat $Addresses] + set multiline 0 + } else { + # range of numbers + set display_number "$lown-$highn" + set display_lines "$lowl-$highl" + set multiline 1 + } + } elseif {$Number != {}} { + set New 0 + set multiline 0 + set display_number $Number + } + + # The three frames of this dialog + set bbox [frame $f.bbox]; # for holding OK,CANCEL DELETE buttons + tixLabelFrame $f.exp -label "Experiment" + set exp [$f.exp subwidget frame]; # the "Experiment" frame + tixLabelFrame $f.act -label "Actions" + set act [$f.act subwidget frame]; # the "Actions" frame + + # Setup the button box + button $bbox.ok -text OK -command "$this ok" -width 6 + button $bbox.cancel -text CANCEL -command "$this cancel" + set Delete [button $bbox.delete -text DELETE -command "$this delete_tp"] + pack $bbox.ok $bbox.cancel -side left -padx 10 -expand yes + pack $bbox.delete -side right -padx 10 -expand yes + + # Setup the "Experiment" frame + if {$New} { + set hit_count "N/A" + set thread "N/A" + set _TPassCount 0 + if {!$Exists} { + $Delete configure -state disabled + } + } else { + if {!$multiline} { + set stuff [gdb_get_tracepoint_info $Number] + # 0=file 1=func 2=line 3=addr 4=disposition 5=passCount 6=stepCount + # 7=thread 8=hitCount 9=actions + set enabled [lindex $stuff 4] + set _TPassCount [lindex $stuff 5] + set thread [lindex $stuff 7] + set hit_count [lindex $stuff 8] + set actions [lindex $stuff 9] + if {$File == {}} { + set File [lindex $stuff 0] + } + if {$Lines == {} && $Addresses == {}} { + set Addresses [lindex $stuff 3] + set display_lines $Addresses + } + if {$functions == {}} { + set functions [lindex $stuff 1] + } + } else { + # ummm... + set hit_count "N/A" + set thread "N/A" + + # !! Assumptions... + set stuff [gdb_get_tracepoint_info [lindex $Number 0]] + set _TPassCount [lindex $stuff 5] + set actions [lindex $stuff 9] + } + } + + # Number + label $exp.numlbl -text {Number:} + label $exp.number -text $display_number + + # File + label $exp.fillbl -text {File:} + label $exp.file -text $File + # Line + if {$Lines != {}} { + label $exp.linlbl -text {Line(s):} + } else { + label $exp.linlbl -text {Address(es):} + } + label $exp.line -text $display_lines + + # Function + if {[llength $functions] > 1} { + # Do not allow this until we clean up the action dialog... + tk_messageBox -type ok -icon error \ + -message "Cannot set tracepoint ranges across functions!" + after idle manage delete $this + } + #set functions [join $functions ,] + label $exp.funlbl -text {Function:} + label $exp.funct -text [concat $functions] + + # Hit count + label $exp.hitlbl -text {Hit Count:} + label $exp.hit -text $hit_count + + # Thread + label $exp.thrlbl -text {Thread:} + label $exp.thread -text $thread + + # Place these onto the screen + grid $exp.numlbl -row 0 -column 0 -sticky w -padx 10 -pady 1 + grid $exp.number -row 0 -column 1 -sticky w -padx 10 -pady 1 + grid $exp.funlbl -row 0 -column 2 -sticky w -padx 10 -pady 1 + grid $exp.funct -row 0 -column 3 -sticky w -padx 10 -pady 1 + grid $exp.hitlbl -row 1 -column 0 -sticky w -padx 10 -pady 1 + grid $exp.hit -row 1 -column 1 -sticky w -padx 10 -pady 1 + grid $exp.fillbl -row 1 -column 2 -sticky w -padx 10 -pady 1 + grid $exp.file -row 1 -column 3 -sticky w -padx 10 -pady 1 + grid $exp.thrlbl -row 2 -column 0 -sticky w -padx 10 -pady 1 + grid $exp.thread -row 2 -column 1 -sticky w -padx 10 -pady 1 + grid $exp.linlbl -row 2 -column 2 -sticky w -padx 10 -pady 1 + grid $exp.line -row 2 -column 3 -sticky w -padx 10 -pady 1 + + # Configure columns + grid columnconfigure $exp 0 -weight 1 + grid columnconfigure $exp 1 -weight 1 + grid columnconfigure $exp 2 -weight 1 + grid columnconfigure $exp 3 -weight 1 + + # The "Actions" Frame + set pass_frame [frame $act.pass] + set act_frame [frame $act.actions] + set new_frame [frame $act.new] + + # Pack these frames + pack $pass_frame -fill x + pack $act_frame -fill both -expand 1 + pack $new_frame -side top -fill x + + # Passes + label $pass_frame.lbl -text {Number of Passes:} + entry $pass_frame.ent -textvariable _TPassCount -width 5 + pack $pass_frame.lbl -side left -padx 10 -pady 5 + pack $pass_frame.ent -side right -padx 10 -pady 5 + + # Actions + tixScrolledListBox $act_frame.lb -scrollbar auto + set ActionLB [$act_frame.lb subwidget listbox] + $ActionLB configure -selectmode multiple -exportselection 0 + label $act_frame.lbl -text {Actions} + pack $act_frame.lbl -side top + pack $act_frame.lb -side bottom -fill both -expand 1 -padx 5 -pady 5 + $act_frame.lb configure -command "$this edit" \ + -browsecmd "$this set_delete_action_state $ActionLB $new_frame.del_but" + + # New actions + combobox::combobox $new_frame.combo -maxheight 15 -editable 0 -font src-font \ + -command [code $this set_action_type] + $new_frame.combo list insert end collect while-stepping + $new_frame.combo entryset collect + + button $new_frame.add_but -text {Add} -command "$this add_action" + pack $new_frame.combo $new_frame.add_but -side left -fill x \ + -padx 5 -pady 5 + + button $new_frame.del_but -text {Delete} -state disabled \ + -command "$this delete_action" + pack $new_frame.del_but -side right -fill x \ + -padx 5 -pady 5 + + # Pack the main frames + pack $bbox -side bottom -padx 5 -pady 8 -fill x + pack $f.exp -side top -padx 5 -pady 2 -fill x + pack $f.act -side top -padx 5 -pady 2 -expand yes -fill both + + # If we are not new, add all actions + if {!$New} { + add_all_actions $actions + } + + # !! FOR SOME REASON, THE *_FRAMES DO NOT GET MAPPED WHENEVER THE USER + # WAITS A FEW SECONDS TO PLACE THIS DIALOG ON THE SCREEN. This is here + # as a workaround so that the action-related widgets don't disappear... + #update idletasks + } + + method set_action_type {widget action} { + set ActionType $action + } + + method add_action {} { + + if {"$ActionType" == "while-stepping"} { + if {$WhileStepping} { + # We are only allowed on of these... + tk_messageBox -icon error -type ok \ + -message "A tracepoint may only have one while-stepping action." + return + } + set whilestepping 1 + set step_args "-Steps 1" + } else { + set whilestepping 0 + set step_args {} + } + + #debug "ADDING ACTION FOR $File:[lindex $Lines 0]" + if {$Lines != {}} { + set ActionsDlg [eval manage create actiondlg -File $File \ + -Line [lindex $Lines 0] \ + -WhileStepping $whilestepping -Number [lindex $Number 0]\ + -Callback \"$this done\" $step_args] + } else { + set ActionsDlg [eval manage create actiondlg -File $File \ + -Address [lindex $Addresses 0] \ + -WhileStepping $whilestepping -Number [lindex $Number 0]\ + -Callback \"$this done\" $step_args] + } + } + + method delete_action {} { + # If we just delete these from the action list, they will get deleted + # when the user presses OK. + + set selected_elem [lsort -integer -decreasing [$ActionLB curselection]] + foreach elem $selected_elem { + $ActionLB delete $elem + } + } + + method set_delete_action_state {list but} { + if {[$list curselection] == ""} { + $but configure -state disabled + } else { + $but configure -state normal + } + } + + method done {status {steps 0} {data {}}} { + + # We have just returned from the ActionDlg: must reinstall our grab +# after idle grab $this + + switch $status { + cancel { + # Don't do anything + set ActionsDlg {} + return + } + add { + add_action_to_list $steps $data + set ActionsDlg {} + } + delete { + # do something + set ActionsDlg {} + } + modify { + # Delete the current selection and insert the new one in its place + $ActionLB delete $Selection + add_action_to_list $steps $data $Selection + set ActionsDlg {} + } + default { + debug "Unknown status from ActionDlg : \"$status\"" + } + } + } + + method add_action_to_list {steps data {index {}}} { + + set data [join $data ,] + + if {$steps > 0} { + if {"$index" == ""} { + set index "end" + } + $ActionLB insert $index "while-stepping ($steps): $data" + set WhileStepping 1 + } else { + if {"$index" == ""} { + set index 0 + } + $ActionLB insert $index "collect: $data" + } + } + + # ------------------------------------------------------------------ + # METHOD: cancel - cancel the dialog and do not set the trace + # ------------------------------------------------------------------ + method cancel {} { + manage delete $this + } + + # ------------------------------------------------------------------ + # METHOD: ok - validate the tracepoint and install it + # ------------------------------------------------------------------ + method ok {} { + + # We "dismiss" the dialog here... + wm withdraw [winfo toplevel [namespace tail $this]] + + set actions [get_actions] + # Check that we are collecting data + + # This is silly, but, hey, it works. + # Lines is the line number where the tp is + # in case of a tp-range it is the set of lines for that range + if {$Lines != {}} { + for {set i 0} {$i < [llength $Number]} {incr i} { + set number [lindex $Number $i] + set line [lindex $Lines $i] + + if {$number == -1} { + #debug "Adding new tracepoint at $File:$line $_TPassCount $actions" + set err [catch {gdb_add_tracepoint $File:$line $_TPassCount $actions} errTxt] + } else { + if {$New && $Exists} { + set result [tk_messageBox -icon error -type yesno \ + -message "Overwrite actions for tracepoint \#$number at $File:$line?" \ + -title "Query"] + if {"$result" == "no"} { + continue + } + } + if {$New == 0 && $Exists == 1} { + set tpnum [gdb_tracepoint_exists "$File:$line"] + if {$tpnum == -1} { + tk_messageBox -type ok -icon error -message "Tracepoint was deleted" + manage delete $this + return + } + } + + #debug "Editing tracepoint \#$Number: $_TPassCount $actions" + set err [catch {gdb_edit_tracepoint $number $_TPassCount $actions} errTxt] + } + + if {$err} { + if {$number == -1} { + set str "adding new tracepoint at $File:$line" + } else { + set str "editing tracepoint $number at $File:$line" + } + tk_messageBox -type ok -icon error -message "Error $str: $errTxt" + } + } + } else { + # Async + for {set i 0} {$i < [llength $Number]} {incr i} { + set number [lindex $Number $i] + set addr [lindex $Addresses $i] + if {$number == -1} { + #debug "Adding new tracepoint at $addr in $File; $_TPassCount $actions" + set err [catch {gdb_add_tracepoint {} $_TPassCount $actions $addr} errTxt] + } else { + if {$New && $Exists} { + set result [tk_messageBox -icon error -type yesno \ + -message "Overwrite actions for tracepoint \#$number at $File:$line?" \ + -title "Query"] + if {"$result" == "no"} { + continue + } + } + if {$New == 0 && $Exists == 1} { + set num [gdb_tracepoint_exists "$File:$Line"] + if {$num == -1} { + tk_messageBox -type ok -icon error -message "Tracepoint was deleted" + manage delete $this + return + } + } + #debug "Editing tracepoint \#$Number: $_TPassCount $actions" + set err [catch {gdb_edit_tracepoint $number $_TPassCount $actions} errTxt] + } + + if {$err} { + if {$number == -1} { + set str "adding new tracepoint at $addr in $File" + } else { + set str "editing tracepoint $number at $addr in $File" + } + tk_messageBox -type ok -icon error -message "Error $str: $errTxt" + } + } + } + + manage delete $this + } + + method cmd {line} { + $line + } + + method delete_tp {} { + debug "deleting tracepoint $Number" + set err [catch {gdb_cmd "delete tracepoints $Number"} errTxt] + debug "done deleting tracepoint $Number" + manage delete $this + } + + method get_data {action} { + + set data {} + foreach a $action { + set datum [string trim $a \ \r\n\t,] + if {"$datum" == "collect" || "$datum" == ""} { + continue + } + + lappend data $datum + } + + return $data + } + + method add_all_actions {actions} { + + set length [llength $actions] + for {set i 0} {$i < $length} {incr i} { + set action [lindex $actions $i] + + if {[regexp "collect" $action]} { + set steps 0 + set data [get_data $action] + } elseif {[regexp "while-stepping" $action]} { + scan $action "while-stepping %d" steps + incr i + set action [lindex $actions $i] + set data [get_data $action] + } elseif {[regexp "end" $action]} { + continue + } + + # Now have an action: data and steps + add_action_to_list $steps $data + } + } + + method get_actions {} { + + set actions {} + set list [$ActionLB get 0 end] + foreach action $list { + if {[regexp "collect" $action]} { + scan $action "collect: %s" data + set steps 0 + set whilestepping 0 + } elseif {[regexp "while-stepping" $action]} { + scan $action "while-stepping (%d): %s" steps data + set whilestepping 1 + } else { + debug "unknown action: $action" + continue + } + + lappend actions [list $steps $data] + } + + return $actions + } + + method edit {} { + + set Selection [$ActionLB curselection] + set action [$ActionLB get $Selection] + if [regexp "collect" $action] { + scan $action "collect: %s" data + set steps 0 + set whilestepping 0 + } elseif [regexp "while-stepping" $action] { + scan $action "while-stepping (%d): %s" steps data + set whilestepping 1 + } else { + debug "unknown action: $action" + return + } + + set data [split $data ,] + set len [llength $data] + set real_data {} + set special 0 + for {set i 0} {$i < $len} {incr i} { + set a [lindex $data $i] + if {[string range $a 0 1] == "\$("} { + set special 1 + set b $a + } elseif {$special} { + lappend b $a + if {[string index $a [expr {[string length $a]-1}]] == ")"} { + lappend real_data [join $b ,] + set special 0 + } + } else { + lappend real_data $a + } + } + + # !! lindex $Lines 0 -- better way? + if {$Lines != {}} { + manage create actiondlg -File $File -Line [lindex $Lines 0] \ + -WhileStepping $whilestepping -Number [lindex $Number 0] \ + -Callback "$this done" -Data $real_data -Steps $steps + } else { + manage create actiondlg -File $File -Address [lindex $Addresses 0] \ + -WhileStepping $whilestepping -Number [lindex $Number 0] \ + -Callback "$this done" -Data $real_data -Steps $steps + } + } + + method get_selection {} { + + set action [$ActionLB curselection] + return [$ActionLB get $action] + } + + # ------------------------------------------------------------------ + # METHOD: title - Title the trace dialog. + # + # This is needed to title the window after the dialog has + # been created. The window manager actually sets our title + # after we've been created, so we need to do this in an + # "after idle". + # ------------------------------------------------------------------ + method title {} { + if {$New} { + set display_number "N/A" + wm title [winfo toplevel [namespace tail $this]] "Add Tracepoint" + } else { + wm title [winfo toplevel [namespace tail $this]] "Edit Tracepoint" + } + } + + # PUBLIC DATA + public File {} + public Lines {} + public Addresses {} + public Number {} + + # PROTECTED DATA + protected Delete + protected _TPassCount + protected ActionType {} + protected ActionLB + protected Actions + protected WhileStepping 0 + protected Selection {} + protected New 0; # set whenever there is a new tp to add + protected Exists 0; # set whenever a tracepoint in the range exists + protected Dismissed 0; # has this dialog been dismissed already? + protected ActionsDlg {} +} + +proc gdb_add_tracepoint {where passes actions {addr {}}} { + #debug "gdb_add_tracepoint $where $passes $actions $addr" + + # Install the tracepoint + if {$where == "" && $addr != ""} { + set where "*$addr" + } + + #debug "trace $where" + set err [catch {gdb_cmd "trace $where"} errTxt] + + if {$err} { + tk_messageBox -type ok -icon error -message $errTxt + return + } + + # Get the number for this tracepoint + set number [gdb_tracepoint_exists $where] + + # If there is a pass count, add that, too + set err [catch {gdb_cmd "passcount $passes $number"} errTxt] + + if {$err} { + tk_messageBox -type ok -icon error -message $errTxt + return + } + + set real_actions {} + foreach action $actions { + set steps [lindex $action 0] + set data [lindex $action 1] + + if {$steps} { + lappend real_actions "while-stepping $steps" + lappend real_actions "collect $data" + lappend real_actions "end" + } else { + lappend real_actions "collect $data" + } + } + + if {[llength $real_actions] > 0} { + lappend real_actions "end" + } + + set err [catch {gdb_actions $number $real_actions} errTxt] + if $err { + set errTxt "$errTxt Tracepoint will be installed with no actions" + tk_messageBox -type ok -icon error -message $errTxt + return + } +} + +proc gdb_edit_tracepoint {number passes actions} { + #debug "gdb_edit_tracepoint $number $passes $actions" + + # If there is a pass count, add that, too + set err [catch {gdb_cmd "passcount $passes $number"} errTxt] + + if $err { + tk_messageBox -type ok -icon error -message $errTxt + return + } + + set real_actions {} + foreach action $actions { + set steps [lindex $action 0] + set data [lindex $action 1] + + if $steps { + lappend real_actions "while-stepping $steps" + lappend real_actions "collect $data" + lappend real_actions "end" + } else { + lappend real_actions "collect $data" + } + } + + if {[llength $real_actions] > 0} { + lappend real_actions "end" + } + + gdb_actions $number $real_actions +} diff --git a/gdb/gdbtk/library/util.tcl b/gdb/gdbtk/library/util.tcl new file mode 100644 index 00000000000..dc8007d92f5 --- /dev/null +++ b/gdb/gdbtk/library/util.tcl @@ -0,0 +1,346 @@ +# Utilities for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Misc routines +# +# PROCS: +# +# keep_raised - keep a window raised +# sleep - wait a certain number of seconds and return +# toggle_debug_mode - turn debugging on and off +# freeze - make a window modal +# bp_exists - does a breakpoint exist on linespec? +# +# ---------------------------------------------------------------------- +# + + +# A helper procedure to keep a window on top. +proc keep_raised {top} { + if {[winfo exists $top]} { + wm deiconify $top + raise $top + after 1000 [info level 0] + } +} + +# sleep - wait a certain number of seconds then return +proc sleep {sec} { + global __sleep_timer + set __sleep_timer 0 + after [expr {1000 * $sec}] set __sleep_timer 1 + vwait __sleep_timer +} + + +# ------------------------------------------------------------------ +# PROC: auto_step - automatically step through a program +# ------------------------------------------------------------------ + +# FIXME FIXME +proc auto_step {} { + global auto_step_id + + set auto_step_id [after 2000 auto_step] + gdb_cmd next +} + +# ------------------------------------------------------------------ +# PROC: auto_step_cancel - cancel auto-stepping +# ------------------------------------------------------------------ + +proc auto_step_cancel {} { + global auto_step_id + + if {[info exists auto_step_id]} { + after cancel $auto_step_id + unset auto_step_id + } +} + +# ------------------------------------------------------------------ +# PROC: tfind_cmd -- to execute a tfind command on the target +# ------------------------------------------------------------------ +proc tfind_cmd {command} { + gdbtk_busy + # need to call gdb_cmd because we want to ignore the output + set err [catch {gdb_cmd $command} msg] + if {$err || [regexp "Target failed to find requested trace frame" $msg]} { + tk_messageBox -icon error -title "GDB" -type ok \ + -modal task -message $msg + gdbtk_idle + return + } else { + gdbtk_update + gdbtk_idle + } +} + +# ------------------------------------------------------------------ +# PROC: save_trace_command -- Saves the current trace settings to a file +# ------------------------------------------------------------------ +proc save_trace_commands {} { + + set out_file [tk_getSaveFile -title "Enter output file for trace commands"] + debug "Got outfile: $out_file" + if {$out_file != ""} { + gdb_cmd "save-tracepoints $out_file" + } +} + +# ------------------------------------------------------------------ +# PROC: do_test - invoke the test passed in +# This proc is provided for convenience. For any test +# that uses the console window (like the console window +# tests), the file cannot be sourced directly using the +# 'tk' command because it will block the console window +# until the file is done executing. This proc assures +# that the console window is free for input by wrapping +# the source call in an after callback. +# Users may also pass in the verbose and tests globals +# used by the testsuite. +# ------------------------------------------------------------------ +proc do_test {{file {}} {verbose {}} {tests {}}} { + global _test + + if {$file == {}} { + error "wrong \# args: should be: do_test file ?verbose? ?tests ...?" + } + + if {$verbose != {}} { + set _test(verbose) $verbose + } elseif {![info exists _test(verbose)]} { + set _test(verbose) 0 + } + + if {$tests != {}} { + set _test(tests) $tests + } + + set _test(interactive) 1 + after 500 [list source $file] +} + +# ------------------------------------------------------------------ +# PROCEDURE: gdbtk_read_defs +# Reads in the defs file for the testsuite. This is usually +# the first procedure called by a test file. It returns +# 1 if it was successful and 0 if not (if run interactively +# from the console window) or exits (if running via dejagnu). +# ------------------------------------------------------------------ +proc gdbtk_read_defs {} { + global _test env + + if {[info exists env(DEFS)]} { + set err [catch {source $env(DEFS)} errTxt] + } else { + set err [catch {source defs} errTxt] + } + + if {$err} { + if {$_test(interactive)} { + tk_messageBox -icon error -message "Cannot load defs file:\n$errTxt" -type ok + return 0 + } else { + puts stdout "cannot load defs files: $errTxt\ntry setting DEFS" + exit 1 + } + } + + return 1 +} + +# ------------------------------------------------------------------ +# PROCEDURE: bp_exists +# Returns BPNUM if a breakpoint exists at LINESPEC or +# -1 if no breakpoint exists there +# ------------------------------------------------------------------ +proc bp_exists {linespec} { + + lassign $linespec foo function filename line_number addr pc_addr + + set bps [gdb_get_breakpoint_list] + foreach bpnum $bps { + set bpinfo [gdb_get_breakpoint_info $bpnum] + lassign $bpinfo file func line pc type enabled disposition \ + ignore_count commands cond thread hit_count + if {$filename == $file && $function == $func && $addr == $pc} { + return $bpnum + } + } + + return -1 +} + + +# Scrolled Listbox - this could be in libgui, +# but we'll probably just start using new iwidgets stuff +# soon so keep it here temporarily. This is based on +# code from Welch's book. + +proc CygScrolledListbox { win args } { + frame $win + # Create listbox attached to scrollbars, pass thru $args + eval {listbox $win.list -yscrollcommand [list $win.sy set]} $args + scrollbar $win.sy -orient vertical -command [list $win.list yview] + + # Create padding based on the scrollbar width and border + set pad [expr [$win.sy cget -width] + 2* \ + ([$win.sy cget -bd] + \ + [$win.sy cget -highlightthickness])] + + frame $win.pad -width $pad -height $pad + pack $win.sy -side right -fill y + pack $win.list -side left -fill both -expand true + return $win.list +} + +# gridCGet - This provides the missing grid cget +# command. + +proc gridCGet {slave option} { + set config_list [grid info $slave] + return [lindex $config_list [expr [lsearch $config_list $option] + 1]] +} + +# ------------------------------------------------------------------ +# PROC: find_iwidgets_library - Find the IWidgets library. +# +# This is a little bit of bogosity which is necessary so we +# can find the iwidgets libraries if we are not installed: +# The problem is that the iwidgets are really weird. The init file is +# in the build tree, but all the library files are in the source tree... +# +# ------------------------------------------------------------------ +proc find_iwidgets_library {} { + + set IwidgetsOK 1 + + if {[catch {package require Iwidgets 3.0} errMsg]} { + + # OK, we are not installed or this would have succeeded... + # Lets try to do it by hand: + set IwidgetsOK 0 + + set iwidgetsSrcDir [glob -nocomplain [file join \ + [file dirname [file dirname $::tcl_library]] \ + itcl iwidgets*]] + + # Canonicalize the executable's directory name. It turns out that on Solaris, + # info nameofexecutable returns /foo/bar/real_dir/./gdb when gdb is launched from + # another gdb session, so we have to fix this up. + + set exec_name [info nameofexecutable] + set curdir [pwd] + cd [file dirname $exec_name] + set exec_name [pwd] + cd $curdir + + set iwidgetsBuildDir [glob -nocomplain [file join \ + [file dirname $exec_name] \ + itcl iwidgets*]] + + if {[llength $iwidgetsSrcDir] == 1 && [llength $iwidgetsBuildDir] == 1} { + # The lindex is necessary because the path may have spaces in it... + set initFile [file join [lindex $iwidgetsBuildDir 0] \ + $::tcl_platform(platform) iwidgets.tcl] + set libDir [file join [lindex $iwidgetsSrcDir 0] generic] + if {[file exists $initFile] && [file isdirectory $libDir]} { + if {![catch {source $initFile} err]} { + # Now fix up the stuff the Iwidgets init file got wrong... + set libPos [lsearch $::auto_path [file join $::iwidgets::library scripts]] + if {$libPos >= 0} { + set auto_path [lreplace $::auto_path $libPos $libPos $libDir] + } else { + lappend ::auto_path $libDir + } + set ::iwidgets::library $libDir + set IwidgetsOK 1 + } else { + append errMsg "\nError in iwidgets.tcl file: $err" + } + } + } else { + append errMsg "\nCould not find in-place versions of the Iwidgets files\n" + append errMsg "Looked at: [file join [file dirname\ + [file dirname $::tcl_library]] itcl iwidgets*]\n" + append errMsg "and: [file join [file dirname \ + [info nameofexecutable]] itcl iwidgets*]\n" + } + + } + return $IwidgetsOK +} + +# ------------------------------------------------------------------ +# PROC: get_disassembly_flavor - gets the current disassembly flavor. +# The set disassembly-flavor command is assumed to exist. This +# will error out if it does not. +# ------------------------------------------------------------------ +proc get_disassembly_flavor {} { + if {[catch {gdb_cmd "show disassembly-flavor"} ret]} { + return "" + } else { + regexp {\"([^\"]*)\"\.} $ret dummy gdb_val + return $gdb_val + } +} + +# ------------------------------------------------------------------ +# PROC: list_disassembly_flavors - Lists the current disassembly flavors. +# Returns an empty list if the set disassembly-flavor is not supported. +# ------------------------------------------------------------------ +proc list_disassembly_flavors {} { + catch {gdb_cmd "set disassembly-flavor"} ret_val + if {[regexp {Requires an argument\. Valid arguments are (.*)\.} \ + $ret_val dummy list]} { + foreach elem [split $list ","] { + lappend vals [string trim $elem] + } + return [lsort $vals] + } else { + return {} + } +} + +# ------------------------------------------------------------------ +# PROC: init_disassembly_flavor - Synchs up gdb's internal disassembly +# flavor with the value in the preferences file. +# ------------------------------------------------------------------ +proc init_disassembly_flavor {} { + set gdb_val [get_disassembly_flavor] + if {$gdb_val != ""} { + set def_val [pref get gdb/src/disassembly-flavor] + if {[string compare $def_val ""] != 0} { + if {[catch "gdb_cmd \"set disassembly-flavor $def_val\""]} { + pref set gdb/src/disassembly-flavor $gdb_val + } + } else { + pref set gdb/src/disassembly-flavor $gdb_val + } + } +} + +# ------------------------------------------------------------------ +# PROC: list_element_strcmp - to be used in lsort -command when the +# elements are themselves lists, and you always want to look at +# a particular item. +# ------------------------------------------------------------------ +proc list_element_strcmp {index first second} { + set theFirst [lindex $first $index] + set theSecond [lindex $second $index] + + return [string compare $theFirst $theSecond] +} diff --git a/gdb/gdbtk/library/variables.tcl b/gdb/gdbtk/library/variables.tcl new file mode 100644 index 00000000000..a1f15e2741d --- /dev/null +++ b/gdb/gdbtk/library/variables.tcl @@ -0,0 +1,959 @@ +# Variable display window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements variable windows for gdb. LocalsWin and WatchWin both +# inherit from this class. You need only override the method +# 'getVariablesBlankPath' and a few other things... +# ---------------------------------------------------------------------- + +class VariableWin { + inherit EmbeddedWin GDBWin + protected variable Sizebox 1 + + # ------------------------------------------------------------------ + # CONSTRUCTOR - create new watch window + # ------------------------------------------------------------------ + constructor {args} { + # + # Create a window with the same name as this object + # + gdbtk_busy + set _queue [Queue \#auto] + build_win $itk_interior + gdbtk_idle + + add_hook gdb_update_hook "$this update" + add_hook gdb_busy_hook "$this disable_ui" + add_hook gdb_no_inferior_hook "$this no_inferior" + add_hook gdb_idle_hook [list $this idle] + add_hook gdb_clear_file_hook [code $this clear_file] + } + + # ------------------------------------------------------------------ + # METHOD: build_win - build the watch window + # ------------------------------------------------------------------ + method build_win {f} { + global tixOption tcl_platform Display + # debug "VariableWin::build_win" + set width [font measure src-font "W"] + # Choose the default width to be... + set width [expr {40 * $width}] + if {$tcl_platform(platform) == "windows"} { + set scrollmode both + } else { + set scrollmode auto + } + + debug "tree=$f.tree" + set Tree [tixTree $f.tree \ + -opencmd "$this open" \ + -closecmd "$this close" \ + -ignoreinvoke 1 \ + -width $width \ + -browsecmd [list $this selectionChanged] \ + -scrollbar $scrollmode \ + -sizebox $Sizebox] + if {![pref get gdb/mode]} { + $Tree configure -command [list $this editEntry] + } + set Hlist [$Tree subwidget hlist] + + # FIXME: probably should use columns instead. + $Hlist configure -header 1 + + set l [expr {$EntryLength - $Length - [string length "Name"]}] + # Ok, this is as hack as it gets + set blank " " + $Hlist header create 0 -itemtype text \ + -text "Name[string range $blank 0 $l]Value" + + # Configure the look of the tree + set sbg [$Hlist cget -bg] + set fg [$Hlist cget -fg] + set bg $tixOption(input1_bg) + set width [font measure src-font $LengthString] + $Hlist configure -indent $width -bg $bg \ + -selectforeground $fg -selectbackground $sbg \ + -selectborderwidth 0 -separator . -font src-font + + # Get display styles + set normal_fg [$Hlist cget -fg] + set highlight_fg [pref get gdb/variable/highlight_fg] + set disabled_fg [pref get gdb/variable/disabled_fg] + set NormalTextStyle [tixDisplayStyle text -refwindow $Hlist \ + -bg $bg -fg $normal_fg -font src-font] + set HighlightTextStyle [tixDisplayStyle text -refwindow $Hlist \ + -bg $bg -fg $highlight_fg -font src-font] + set DisabledTextStyle [tixDisplayStyle text -refwindow $Hlist \ + -bg $bg -fg $disabled_fg -font src-font] + + if {[catch {gdb_cmd "show output-radix"} msg]} { + set Radix 10 + } else { + regexp {[0-9]+} $msg Radix + } + + + # Update the tree display + update + pack $Tree -expand yes -fill both + + # Create the popup menu for this widget + bind $Hlist <3> "$this postMenu %X %Y" + bind $Hlist <KeyPress-space> [code $this toggleView] + + # Do not use the tixPopup widget... + set Popup [menu $f.menu -tearoff 0] + set disabled_foreground [$Popup cget -foreground] + $Popup configure -disabledforeground $disabled_foreground + set ViewMenu [menu $Popup.view] + + # Populate the view menu + $ViewMenu add radiobutton -label "Hex" -variable Display($this) \ + -value hexadecimal + $ViewMenu add radiobutton -label "Decimal" -variable Display($this) \ + -value decimal + $ViewMenu add radiobutton -label "Binary" -variable Display($this) \ + -value binary + $ViewMenu add radiobutton -label "Octal" -variable Display($this) \ + -value octal + $ViewMenu add radiobutton -label "Natural" -variable Display($this) \ + -value natural + + $Popup add command -label "dummy" -state disabled + $Popup add separator + $Popup add cascade -label "Format" -menu $ViewMenu + # $Popup add checkbutton -label "Auto Update" + # $Popup add command -label "Update Now" + if {![pref get gdb/mode]} { + $Popup add command -label "Edit" + } + + # Make sure to update menu info. + selectionChanged "" + + window_name "Local Variables" "Locals" + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - destroy window containing widget + # ------------------------------------------------------------------ + destructor { + # debug "VariableWin::destructor" + # Make sure to clean up the frame + catch {destroy $_frame} + + # Delete the display styles used with this window + destroy $NormalTextStyle + destroy $HighlightTextStyle + destroy $DisabledTextStyle + + # Remove this window and all hooks + remove_hook gdb_update_hook "$this update" + remove_hook gdb_busy_hook "$this disable_ui" + remove_hook gdb_no_inferior_hook "$this no_inferior" + remove_hook gdb_idle_hook [list $this idle] + remove_hook gdb_clear_file_hook [code $this clear_file] + } + + # ------------------------------------------------------------------ + # METHOD: clear_file - Clear out state and prepare for loading + # a new executable. + # ------------------------------------------------------------------ + method clear_file {} { + no_inferior + } + + # ------------------------------------------------------------------ + # METHOD: reconfig - used when preferences change + # ------------------------------------------------------------------ + method reconfig {} { + # debug "VariableWin::reconfig" + foreach win [winfo children $itk_interior] { + destroy $win + } + + build_win $itk_interior + } + + # ------------------------------------------------------------------ + # METHOD: build_menu_helper - Create the menu for a subclass. + # ------------------------------------------------------------------ + method build_menu_helper {first} { + global Display + menu [namespace tail $this].mmenu + + [namespace tail $this].mmenu add cascade -label $first -underline 0 -menu [namespace tail $this].mmenu.var + + menu [namespace tail $this].mmenu.var + if {![pref get gdb/mode]} { + [namespace tail $this].mmenu.var add command -label Edit -underline 0 -state disabled \ + -command [format { + %s editEntry [%s getSelection] + } $this $this] + } + [namespace tail $this].mmenu.var add cascade -label Format -underline 0 \ + -menu [namespace tail $this].mmenu.var.format + + menu [namespace tail $this].mmenu.var.format + foreach label {Hex Decimal Binary Octal Natural} fmt {hexadecimal decimal binary octal natural} { + [namespace tail $this].mmenu.var.format add radiobutton \ + -label $label -underline 0 \ + -value $fmt -variable Display($this) \ + -command [format { + %s setDisplay [%s getSelection] %s + } $this $this $fmt] + } + + # [namespace tail $this].mmenu add cascade -label Update -underline 0 -menu [namespace tail $this].mmenu.update + # menu [namespace tail $this].mmenu.update + + # The -variable is set when a selection is made in the tree. + # [namespace tail $this].mmenu.update add checkbutton -label "Auto Update" -underline 0 \ + # -command [format { + # %s toggleUpdate [%s getSelection] + # } $this $this] + # [namespace tail $this].mmenu.update add command -label "Update Now" -underline 0 \ + # -accelerator "Ctrl+U" -command [format { + # %s updateNow [%s getSelection] + # } $this $this] + + set top [winfo toplevel [namespace tail $this]] + $top configure -menu [namespace tail $this].mmenu + bind_plain_key $top Control-u [format { + if {!$Running} { + if {[%s getSelection] != ""} { + %s updateNow [%s getSelection] + } + } + } $this $this $this] + + return [namespace tail $this].mmenu.var + } + + # Return the current selection, or the empty string if none. + method getSelection {} { + return [$Hlist info selection] + } + + # This is called when a selection is made. It updates the main + # menu. + method selectionChanged {variable} { + global Display + + if {$Running} { + # Clear the selection, too + $Hlist selection clear + return + } + + # if something is being edited, cancel it + if {[info exists EditEntry]} { + UnEdit + } + + if {$variable == ""} { + set state disabled + } else { + set state normal + } + + foreach menu [list [namespace tail $this].mmenu.var [namespace tail $this].mmenu.var.format ] { + set i [$menu index last] + while {$i >= 0} { + if {[$menu type $i] != "cascade"} { + $menu entryconfigure $i -state $state + } + incr i -1 + } + } + + if {$variable != "" && [$variable editable]} { + set state normal + } else { + set state disabled + } + + if {$variable != ""} { + set Display($this) [$variable format] + } + + foreach label {Hex Decimal Binary Octal Natural} { + [namespace tail $this].mmenu.var.format entryconfigure $label + if {$label != "Hex"} { + [namespace tail $this].mmenu.var.format entryconfigure $label -state $state + } + } + # [namespace tail $this].mmenu.update entryconfigure 0 -variable Update($this,$name) + } + + method updateNow {variable} { + # debug "VariableWin::updateNow $variable" + + if {!$Running} { + set text [label $variable] + $Hlist entryconfigure $variable -itemtype text -text $text + } + } + + method getEntry {x y} { + set realY [expr {$y - [winfo rooty $Hlist]}] + + # Get the tree entry which we are over + return [$Hlist nearest $realY] + } + + method editEntry {variable} { + if {!$Running} { + if {$variable != "" && [$variable editable]} { + edit $variable + } + } + } + + method postMenu {X Y} { + global Update Display + # debug "VariableWin::postMenu" + + # Quicky for menu posting problems.. How to unpost and post?? + + if {[winfo ismapped $Popup] || $Running} { + return + } + + set variable [getEntry $X $Y] + if {[string length $variable] > 0} { + # Configure menu items + # the title is always first.. + #set labelIndex [$Popup index "dummy"] + set viewIndex [$Popup index "Format"] + # set autoIndex [$Popup index "Auto Update"] + # set updateIndex [$Popup index "Update Now"] + set noEdit [catch {$Popup index "Edit"} editIndex] + + # Retitle and set update commands + $Popup entryconfigure 0 -label "[$variable name]" + # $Popup entryconfigure $autoIndex -command "$this toggleUpdate \{$entry\}" \ + -variable Update($this,$entry) + # $Popup entryconfigure $updateIndex -command "$this updateNow \{$entry\}" + + # Edit pane + if {$variable != "" && [$variable editable]} { + if {!$noEdit} { + $Popup delete $editIndex + } + if {![pref get gdb/mode]} { + $Popup add command -label Edit -command "$this edit \{$variable\}" + } + } else { + if {!$noEdit} { + $Popup delete $editIndex + } + } + + # Set view menu + set Display($this) [$variable format] + foreach i {0 1 2 3 4} fmt {hexadecimal decimal binary octal natural} { + debug "configuring entry $i ([$ViewMenu entrycget $i -label]) to $fmt" + $ViewMenu entryconfigure $i \ + -command "$this setDisplay \{$variable\} $fmt" + } + + tk_popup $Popup $X $Y + } + } + + # ------------------------------------------------------------------ + # METHOD edit -- edit a variable + # ------------------------------------------------------------------ + method edit {variable} { + global Update tixOption + + # disable menus + selectionChanged "" + debug "editing \"$variable\"" + + set fg [$Hlist cget -foreground] + set bg [$Hlist cget -background] + + if {$Editing == ""} { + # Must create the frame + set Editing [frame $Hlist.frame -bg $bg -bd 0 -relief flat] + set lbl [::label $Editing.lbl -fg $fg -bg $bg -font src-font] + set ent [entry $Editing.ent -bg $tixOption(bg) -font src-font] + pack $lbl $ent -side left + } + + if {[info exists EditEntry]} { + # We already are editing something... So reinstall it first + # I guess we discard any changes? + UnEdit + } + + # Update the label/entry widgets for this instance + set Update($this,$variable) 1 + set EditEntry $variable + set label [label $variable 1]; # do not append value + $Editing.lbl configure -text "$label " + $Editing.ent delete 0 end + + # Strip the pointer type, text, etc, from pointers, and such + set err [catch {$variable value} text] + if {$err} {return} + if {[$variable format] == "natural"} { + # Natural formats must be stripped. They often contain + # things like strings and characters after them. + set index [string first \ $text] + if {$index != -1} { + set text [string range $text 0 [expr {$index - 1}]] + } + } + $Editing.ent insert 0 $text + + # Find out what the previous entry is + set previous [getPrevious $variable] + + close $variable + $Hlist delete entry $variable + + set cmd [format { \ + %s add {%s} %s -itemtype window -window %s \ + } $Hlist $variable $previous $Editing] + eval $cmd + + if {[$variable numChildren] > 0} { + $Tree setmode $variable open + } + + # Set focus to entry + focus $Editing.ent + $Editing.ent selection to end + + # Setup key bindings + bind $Editing.ent <Return> "$this changeValue" + bind $Hlist <Return> "$this changeValue" + bind $Editing.ent <Escape> "$this UnEdit" + bind $Hlist <Escape> "$this UnEdit" + } + + method getPrevious {variable} { + set prev [$Hlist info prev $variable] + set parent [$Hlist info parent $variable] + + if {$prev != ""} { + # A problem occurs with PREV if its parent is not the same as the entry's + # parent. For example, consider these variables in the window: + # + foo struct {...} + # - bar struct {...} + # a 1 + # b 2 + # local 0 + # if you attempt to edit "local", previous will be set at "bar.b", not + # "struct bar"... + if {[$Hlist info parent $prev] != $parent} { + # This is the problem! + # Find this object's sibling in that parent and place it there. + set children [$Hlist info children $parent] + set p {} + foreach child $children { + if {$child == $variable} { + break + } + set p $child + } + + if {$p == {}} { + # This is the topmost child + set previous "-before [lindex $children 1]" + } else { + set previous "-after $p" + } + } else { + set previous "-after \{$prev\}" + } + } else { + # this is the first! + set previous "-at 0" + } + + if {$prev == "$parent"} { + # This is the topmost-member of a sub-grouping.. + set previous "-at 0" + } + + return $previous + } + + method UnEdit {} { + set previous [getPrevious $EditEntry] + + $Hlist delete entry $EditEntry + set cmd [format {\ + %s add {%s} %s -itemtype text -text {%s} \ + } $Hlist $EditEntry $previous [label $EditEntry]] + eval $cmd + if {[$EditEntry numChildren] > 0} { + $Tree setmode $EditEntry open + } + + # Unbind + bind $Hlist <Return> {} + bind $Hlist <Escape> {} + if {$Editing != ""} { + bind $Editing.ent <Return> {} + bind $Editing.ent <Escape> {} + } + + unset EditEntry + selectionChanged "" + } + + method changeValue {} { + # Get the old value + set new [string trim [$Editing.ent get] \ \r\n] + if {$new == ""} { + UnEdit + return + } + + if {[catch {$EditEntry value $new} errTxt]} { + tk_messageBox -icon error -type ok -message $errTxt \ + -title "Error in Expression" -parent [winfo toplevel $itk_interior] + focus $Editing.ent + $Editing.ent selection to end + } else { + UnEdit + + # Get rid of entry... and replace it with new value + focus $Tree + } + } + + + # ------------------------------------------------------------------ + # METHOD: toggleView: Toggle open/close the current selection. + # ------------------------------------------------------------------ + method toggleView {} { + + set v [getSelection] + set mode [$Tree getmode $v] + + # In the tixTree widget, "open" means "openable", not that it is open... + + debug "mode=$mode" + switch $mode { + open { + $Tree setmode $v close + open $v + } + + close { + $Tree setmode $v open + close $v + } + + default { + dbug E "What happened?" + } + } + } + + method toggleUpdate {variable} { + global Update + + if {$Update($this,$variable)} { + # Must update value + $Hlist entryconfigure $variable \ + -style $NormalTextStyle \ + -text [label $variable] + } else { + $Hlist entryconfigure $variable \ + -style $DisabledTextStyle + } + ::update + } + + method setDisplay {variable format} { + debug "$variable $format" + if {!$Running} { + $variable format $format + set ::Display($this) $format + $Hlist entryconfigure $variable -text [label $variable] + } + } + + # ------------------------------------------------------------------ + # METHOD: label - used to label the entries in the tree + # ------------------------------------------------------------------ + method label {variable {noValue 0}} { + # Ok, this is as hack as it gets + set blank " " + # Use protected data Length to determine how big variable + # name should be. This should clean the display up a little + set name [$variable name] + set indent [llength [split $variable .]] + set indent [expr {$indent * $Length}] + set len [string length $name] + set l [expr {$EntryLength - $len - $indent}] + set label "$name[string range $blank 0 $l]" + #debug "label=$label $noValue" + if {$noValue} { + return $label + } + + set err [catch {$variable value} value] + set value [string trim $value \ \r\t\n] + #debug "err=$err value=$value" + + # Insert the variable's type for things like ptrs, etc. + set type [$variable type] + if {!$err} { + if {$value == "{...}"} { + set val " $type $value" + } elseif {[string first * $type] != -1} { + set val " ($type) $value" + } elseif {[string first \[ $type] != -1} { + set val " $type" + } else { + set val " $value" + } + } else { + set val " $value" + } + + return "$label $val" + } + + # ------------------------------------------------------------------ + # METHOD: open - used to open an entry in the variable tree + # ------------------------------------------------------------------ + method open {path} { + global Update + # We must lookup all the variables for this struct + # debug "VariableWin::open $path" + + if {!$Running} { + # Do not open disabled paths + if {$Update($this,$path)} { + cursor watch + populate $path + cursor {} + } + } else { + $Tree setmode $path open + } + } + + # ------------------------------------------------------------------ + # METHOD: close - used to close an entry in the variable tree + # ------------------------------------------------------------------ + method close {path} { + global Update + debug "VariableWin::close $path" + # Close the path and destroy all the entry widgets + + # Cancel any edits + if {[info exists EditEntry]} { + UnEdit + } + + if {!$Running} { + # Only update when we we are not disabled + if {$Update($this,$path)} { + + # Delete the offspring of this entry + $Hlist delete offspring $path + } + } else { + $Tree setmode $path close + } + } + + method isVariable {var} { + + set err [catch {gdb_cmd "output $var"} msg] + if {$err + || [regexp -nocase "no symbol|syntax error" $msg]} { + return 0 + } + + return 1 + } + + # OVERRIDE THIS METHOD + method getVariablesBlankPath {} { + debug "You forgot to override getVariablesBlankPath!!" + return {} + } + + method cmd {cmd} { + eval $cmd + } + + # ------------------------------------------------------------------ + # METHOD: populate - populate an entry in the tree + # ------------------------------------------------------------------ + method populate {parent} { + global Update + debug "VariableWin::populate \"$parent\"" + + if {[string length $parent] == 0} { + set variables [getVariablesBlankPath] + } else { + set variables [$parent children] + } + + debug "variables=$variables" + eval $_queue push $variables + for {set variable [$_queue pop]} {$variable != ""} {set variable [$_queue pop]} { + debug "inserting variable: $variable" + set Update($this,$variable) 1 + + $Hlist add $variable \ + -itemtype text \ + -text [label $variable] + if {[$variable numChildren] > 0} { + # Make sure we get this labeled as openable + $Tree setmode $variable open + } + + # Special case: If we see "public" with no value or type, then we + # have one of our special c++/java children. Open it automagically + # for the user. + if {[string compare [$variable name] "public"] == 0 + && [$variable type] == "" && [$variable value] == ""} { + eval $_queue push [$variable children] + $Tree setmode $variable close + } + } + + debug "done with populate" + } + + # Get all current locals + proc getLocals {} { + + set vars {} + set err [catch {gdb_get_args} v] + if {!$err} { + set vars [concat $vars $v] + } + + set err [catch {gdb_get_locals} v] + if {!$err} { + set vars [concat $vars $v] + } + + debug "--getLocals:\n$vars\n--getLocals" + return [lsort $vars] + } + + method context_switch {} { + set err [catch {gdb_selected_frame} current_frame] + debug "1: err=$err; _frame=\"$_frame\"; current_frame=\"$current_frame\"" + if {$err && $_frame != ""} { + # No current frame + debug "no current frame" + catch {destroy $_frame} + set _frame {} + return 1 + } elseif {$current_frame == "" && $_frame == ""} { + debug "2" + return 0 + } elseif {$_frame == "" || $current_frame != [$_frame address]} { + # We've changed frames. If we knew something about + # the stack layout, we could be more intelligent about + # destroying variables, but we don't know that here (yet). + debug "switching to frame at $current_frame" + + # Destroy the old frame and create the new one + catch {destroy $_frame} + set _frame [Frame ::\#auto $current_frame] + debug "created new frame: $_frame at [$_frame address]" + return 1 + } + + # Nothing changed + debug "3" + return 0 + } + + # OVERRIDE THIS METHOD and call it from there + method update {} { + global Update + debug "VariableWin::update" + + # First, reset color on label to black + foreach w $ChangeList { + catch { + $Hlist entryconfigure $w -style $NormalTextStyle + } + } + + # Tell toplevel variables to update themselves. This will + # give us a list of all the variables in the table that + # have changed values. + set ChangeList {} + set variables [$Hlist info children {}] + foreach var $variables { + # debug "VARIABLE: $var ($Update($this,$var))" + set ChangeList [concat $ChangeList [$var update]] + } + + foreach var $ChangeList { + $Hlist entryconfigure $var \ + -style $HighlightTextStyle \ + -text [label $var] + } + } + + method idle {} { + # Re-enable the UI + enable_ui + } + + # RECURSION!! + method displayedVariables {top} { + # debug "VariableWin::displayedVariables" + set variableList {} + set variables [$Hlist info children $top] + foreach var $variables { + set mode [$Tree getmode $var] + if {$mode == "close"} { + set moreVars [displayedVariables $var] + lappend variableList [join $moreVars] + } + lappend variableList $var + } + + return [join $variableList] + } + + method deleteTree {} { + global Update + debug "deleteTree" + # debug "VariableWin::deleteTree" +# set variables [displayedVariables {}] + + # Delete all HList entries + $Hlist delete all + + # Delete the variable objects +# foreach i [array names Variables] { +# $Variables($i) delete +# unset Variables($i) +# catch {unset Update($this,$i)} +# } + } + + # ------------------------------------------------------------------ + # METHOD: enable_ui + # Enable all ui elements. + # ------------------------------------------------------------------ + method enable_ui {} { + + # Clear fencepost + set Running 0 + cursor {} + } + + # ------------------------------------------------------------------ + # METHOD: disable_ui + # Disable all ui elements that could affect gdb's state + # ------------------------------------------------------------------ + method disable_ui {} { + + # Set fencepost + set Running 1 + + # Cancel any edits + if {[info exists EditEntry]} { + UnEdit + } + + # Change cursor + cursor watch + } + + # ------------------------------------------------------------------ + # METHOD: no_inferior + # Reset this object. + # ------------------------------------------------------------------ + method no_inferior {} { + + # Clear out the Hlist + deleteTree + + # Clear fencepost + set Running 0 + set _frame {} + cursor {} + } + + # ------------------------------------------------------------------ + # METHOD: cursor - change the toplevel's cursor + # ------------------------------------------------------------------ + method cursor {what} { + [winfo toplevel [namespace tail $this]] configure -cursor $what + ::update idletasks + } + + # + # PUBLIC DATA + # + + # + # PROTECTED DATA + # + + # the tixTree widget for this class + protected variable Tree {} + + # the hlist of this widget + protected variable Hlist {} + + # entry widgets which need to have their color changed back to black + # when idle (used in conjunction with update) + protected variable ChangeList {} + + protected variable ViewMenu + protected variable Popup + + # These are for setting the indent level to an number of characters. + # This will help clean the tree a little + common EntryLength 15 + common Length 1 + common LengthString " " + + # These should be common... but deletion? + # Display styles for HList + protected variable HighlightTextStyle + protected variable NormalTextStyle + protected variable DisabledTextStyle + + protected variable Radix + + # Frame object for the selected frame + protected variable _frame {} + + protected variable Editing {} + protected variable EditEntry + + # Fencepost for enable/disable_ui and idle/busy hooks. + protected variable Running 0 + + # little queue for convenience + protected variable _queue {} +} diff --git a/gdb/gdbtk/library/warning.tcl b/gdb/gdbtk/library/warning.tcl new file mode 100644 index 00000000000..1aee2830a98 --- /dev/null +++ b/gdb/gdbtk/library/warning.tcl @@ -0,0 +1,102 @@ +# Warning dialog for GDBtk. +# Copyright 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ----------------------------------------------------------------------------- +# NAME: +# class WarningDlg +# +# DESC: +# This class implements a warning dialog. It has an optional checkbox +# that the user can select to disable all warnings of the same type. +# +# ARGS: +# -ignorable "class" - Causes an ignorable dialog to be created. +# "class" is the warning class that will be either +# displayed or ignored. It may be any string, so +# long as the same string is used for all related +# warning messages. +# +# -message "msg" - Message to be displayed. +# ----------------------------------------------------------------------------- +# + +class WarningDlg { + inherit ManagedWin ModalDialog + + public { + variable ignorable "" + variable message "" + method constructor {args} + } + + protected common ignore +} + +# ----------------------------------------------------------------------------- +# NAME: +# WarningDlg::constructor +# +# DESC: +# Creates the warning dialog. +# ----------------------------------------------------------------------------- +body WarningDlg::constructor {args} { + debug $args + window_name "Warning" + eval itk_initialize $args + + if {$ignorable == ""} { + tk_messageBox -message $message -type ok -icon warning -default ok \ + -parent [winfo toplevel $itk_interior] + delete + return + } else { + if {[info exists ignore($ignorable)]} { + if {$ignore($ignorable)} { + delete + return + } + } else { + set ignore($ignorable) 0 + } + } + + frame $itk_interior.f + frame $itk_interior.f.a -relief raised -bd 1 + frame $itk_interior.f.b -relief raised -bd 1 + set f $itk_interior.f.a + + + label $f.bitmap -bitmap warning + label $f.lab -text $message + pack $f.bitmap $f.lab -side left -padx 10 -pady 10 + + if {$ignorable != ""} { + checkbutton $itk_interior.f.b.ignore -text "Don't show this warning again" \ + -variable [scope ignore($ignorable)] -anchor w + } + + button $itk_interior.f.b.ok -text OK -underline 0 -command [code $this unpost] + bind $itk_interior.f.b.ok <Return> \ + "$itk_interior.f.b.ok flash; $itk_interior.f.b.ok invoke" + focus $itk_interior.f.b.ok + + if {$ignorable != ""} { + pack $itk_interior.f.b.ignore + } + + pack $itk_interior.f.b.ok -expand yes -side left + pack $itk_interior.f.a + pack $itk_interior.f.b -fill x + pack $itk_interior.f +} diff --git a/gdb/gdbtk/library/watch.tcl b/gdb/gdbtk/library/watch.tcl new file mode 100644 index 00000000000..0c227d1e977 --- /dev/null +++ b/gdb/gdbtk/library/watch.tcl @@ -0,0 +1,270 @@ +# Watch window for GDBtk. +# Copyright 1997, 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License (GPL) as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + + +# ---------------------------------------------------------------------- +# Implements watch windows for gdb. Inherits the VariableWin +# class from variables.tcl. +# ---------------------------------------------------------------------- + +class WatchWin { + inherit VariableWin + + # ------------------------------------------------------------------ + # CONSTRUCTOR - create new locals window + # ------------------------------------------------------------------ + constructor {args} { + set Sizebox 0 + + # Only allow one watch window for now... + if {$init} { + set init 0 + } + } + + # ------------------------------------------------------------------ + # METHOD: build_win - build window for watch. This supplants the + # one in VariableWin, so that we can add the entry at the + # bottom. + # ------------------------------------------------------------------ + method build_win {f} { + global tcl_platform + #debug "WatchWin::build_win $f" + + set Menu [build_menu_helper Watch] + $Menu add command -label Remove -underline 0 \ + -command [format { + %s remove [%s getSelection] + } $this $this] + + set f [::frame $f.f] + set treeFrame [frame $f.top] + set entryFrame [frame $f.expr] + VariableWin::build_win $treeFrame + set Entry [entry $entryFrame.ent -font src-font] + button $entryFrame.but -text "Add Watch" -command "$this validateEntry" + pack $f -fill both -expand yes + grid $entryFrame.ent -row 0 -column 0 -sticky news -padx 2 + grid $entryFrame.but -row 0 -column 1 -padx 2 + grid columnconfigure $entryFrame 0 -weight 1 + grid columnconfigure $entryFrame 1 + + if {$tcl_platform(platform) == "windows"} { + grid columnconfigure $entryFrame 1 -pad 20 + ide_sizebox [namespace tail $this].sizebox + place [namespace tail $this].sizebox -relx 1 -rely 1 -anchor se + } + + grid $treeFrame -row 0 -column 0 -sticky news + grid $entryFrame -row 1 -column 0 -padx 5 -pady 5 -sticky news + grid columnconfigure $f 0 -weight 1 + grid rowconfigure $f 0 -weight 1 + window_name "Watch Expressions" + ::update idletasks + # Binding for the entry + bind $entryFrame.ent <Return> "$entryFrame.but flash; $entryFrame.but invoke" + + } + + method selectionChanged {entry} { + VariableWin::selectionChanged $entry + + set state disabled + set entry [getSelection] + foreach var $Watched { + set name [lindex $var 0] + if {"$name" == "$entry"} { + set state normal + break + } + } + + $Menu entryconfigure last -state $state + } + + method validateEntry {} { + if {!$Running} { + debug "Getting entry value...." + set variable [$Entry get] + debug "Got $variable, going to add" + set ok [add $variable] + debug "Added... with ok: $ok" + + $Entry delete 0 end + } + } + + # ------------------------------------------------------------------ + # METHOD: clear_file - Clear out state so that a new executable + # can be loaded. For WatchWins, this means deleting + # the Watched list, in addition to the normal + # VariableWin stuff. + # ------------------------------------------------------------------ + method clear_file {} { + VariableWin::clear_file + set Watched {} + } + + # ------------------------------------------------------------------ + # DESTRUCTOR - delete watch window + # ------------------------------------------------------------------ + destructor { + foreach var $Watched { + $var delete + } + } + + method postMenu {X Y} { +# debug "WatchWin::postMenu $x $y" + + set entry [getEntry $X $Y] + + # Disable "Remove" if we are not applying this to the parent + set found 0 + foreach var $Watched { + set name [lindex $var 0] + if {"$name" == "$entry"} { + set found 1 + break + } + } + + # Ok, nasty, but a sad reality... + set noStop [catch {$Popup index "Remove"} i] + if {!$noStop} { + $Popup delete $i + } + if {$found} { + $Popup add command -label "Remove" -command "$this remove \{$entry\}" + } + + VariableWin::postMenu $X $Y + } + + method remove {entry} { + global Display Update + + # Remove this entry from the list of watched variables + set i [lsearch -exact $Watched $entry] + if {$i == -1} { + debug "WHAT HAPPENED?" + return + } + set Watched [lreplace $Watched $i $i] + + set list [$Hlist info children $entry] + lappend list $entry + $Hlist delete entry $entry + + $entry delete + } + + # ------------------------------------------------------------------ + # METHOD: getVariablesBlankPath + # Overrides VarialbeWin::getVariablesBlankPath. For a Watch Window, + # this method returns a list of watched variables. + # + # ONLY return items that need to be added to the Watch Tree + # (or use deleteTree) + # ------------------------------------------------------------------ + method getVariablesBlankPath {} { +# debug "WatchWin::getVariablesBlankPath" + set list {} + + set variables [displayedVariables {}] + foreach var $variables { + set name [$var name] + set on($name) 1 + } + + foreach var $Watched { + set name [$var name] + if {![info exists on($name)]} { + lappend list $var + } + } + + return $list + } + + method update {} { + global Update Display + debug "START WATCH UPDATE CALLBACK" + catch {populate {}} msg + catch {VariableWin::update} msg + debug "Did VariableWin::update with return \"$msg\"" + + # Make sure all variables are marked as _not_ Openable? + debug "END WATCH UPDATE CALLBACK" + } + + method showMe {} { + debug "Watched: $Watched" + } + + # ------------------------------------------------------------------ + # METHOD: add - add a variable to the watch window + # ------------------------------------------------------------------ + method add {name} { + debug "Trying to add \"$name\" to watch" + + # Strip all the junk after the first \n + set var [split $name \n] + set var [lindex $var 0] + set var [split $var =] + set var [lindex $var 0] + + # Strip out leading/trailing +, -, ;, spaces, commas + set var [string trim $var +-\;\ \r\n,] + + # Make sure that we have a valid variable + set err [catch {gdb_cmd "set variable $var"} errTxt] + if {$err} { + dbug W "ERROR adding variable: $errTxt" + ManagedWin::open WarningDlg -transient \ + -over $this -message [list $errTxt] -ignorable "watchvar" + } else { + if {[string index $var 0] == "\$"} { + # We must make a special attempt at verifying convenience + # variables.. Specifically, these are printed as "void" + # when they are not defined. So if a user type "$_I_made_tbis_up", + # gdb responds with the value "void" instead of an error + catch {gdb_cmd "p $var"} msg + set msg [split $msg =] + set msg [string trim [lindex $msg 1] \ \r\n] + if {$msg == "void"} { + return 0 + } + } + + debug "In add, going to add $name" + # make one last attempt to get errors + set err [catch {set foo($name) 1}] + set err [expr {$err + [catch {expr {$foo($name) + 1}}]}] + if {!$err} { + set var [gdb_variable create -expr $name] + set ::Update($this,$var) 1 + lappend Watched $var + update + return 1 + } + } + + return 0 + } + + protected variable Entry + protected variable Watched {} + protected variable Menu {} + protected common init 1 +} diff --git a/gdb/testsuite/gdb.gdbtk/ChangeLog-gdbtk b/gdb/testsuite/gdb.gdbtk/ChangeLog-gdbtk new file mode 100644 index 00000000000..298d90e6f8a --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/ChangeLog-gdbtk @@ -0,0 +1,83 @@ +1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * testsuite/gdb.gdbtk/cpp_variable.test: Add test (2.75) to verify + that a baseclass member value was effectively changed. + +1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * testsuite/gdb.gdbtk/cpp_variable.test: Update for new variable + code. + +1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * testsuite/gdb.gdbtk/c_variable.test: Update for new variable + code. + +1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * testsuite/gdb.gdbtk/cpp_variable.h (class V): Add type to + virtual function declaration. + +1999-06-08 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * browser.exp: Use untested and not warning when DISPLAY is not found. + * c_variable.exp: Same. + * console.exp: Same. + * cpp_variable.exp: Same. + * srcwin.exp: Same. + + +1999-04-12 Keith Seitz <keiths@cygnus.com> + + * cpp_variable.exp: Pass the "c++" flag to gdb_compile so + that it can grab the right compiler. + +1999-03-16 Martin Hunt <hunt@cygnus.com> + + * srcwin.test (srcwin-4.5): Change variable name + to $b so test will run again. + +1999-02-22 Martin Hunt <hunt@cygnus.com> + + * srcwin.test (move_mouse_to): Fix typo. + +1999-02-03 Martin Hunt <hunt@cygnus.com> + + * console.test (clear_command_line): Add tests 1.5 - 1.8, + which test the new Shift-Up and Shift-Down bindings. + +1999-02-01 Martin Hunt <hunt@cygnus.com> + + * srcwin.test (srcwin-4.3): Fix bp test. + +1999-01-29 Martin Hunt <hunt@cygnus.com> + + * srcwin.test (click): New function that generates an event + at a location. + (srcwin-4.4): New test. Simulate a click on a line and + check for breakpoint set. + (srcwin-4.5): New test. Right-click on a line and select "Continue + to Here" from popup. + + * srcwin.exp: Source srcwin3.test, which will test source window + assembly debugging on executables built without "-g". + +1999-01-29 Martin Hunt <hunt@cygnus.com> + + * srcwin.exp: Add srcwin2.test, which are basically the same + tests as srcwin.test, but run with a missing source file. + + * srcwin2.test: New file. + + * srcwin.test: Add tests for setting breakpoints in the source window, + testing BP balloons, variable balloons, and mixed-mode disassembly + of include files. + + +Local Variables: +mode: change-log +left-margin: 8 +fill-column: 74 +version-control: never +End: + diff --git a/gdb/testsuite/gdb.gdbtk/Makefile.in b/gdb/testsuite/gdb.gdbtk/Makefile.in new file mode 100644 index 00000000000..09fed6d2694 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/Makefile.in @@ -0,0 +1,33 @@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +EXECUTABLES = simple stack c_variable cpp_variable + +# uuencoded format to avoid SCCS/RCS problems with binary files. +CROSS_EXECUTABLES = + +all: + @echo "Nothing to be done for all..." + +info: +install-info: +dvi: +install: +uninstall: force +installcheck: +check: + +clean mostlyclean: + -rm -f *~ *.o a.out xgdb *.x $(CROSS_EXECUTABLES) *.ci *.tmp + -rm -f core core.coremaker coremaker.core corefile $(EXECUTABLES) + -rm -f twice-tmp.c + +distclean maintainer-clean realclean: clean + -rm -f *~ core + -rm -f Makefile config.status config.log + -rm -f arch.inc + -rm -f *-init.exp + -rm -fr *.log summary detail *.plog *.sum *.psum site.* + +Makefile : $(srcdir)/Makefile.in $(srcdir)/configure.in + $(SHELL) ./config.status --recheck diff --git a/gdb/testsuite/gdb.gdbtk/browser.exp b/gdb/testsuite/gdb.gdbtk/browser.exp new file mode 100644 index 00000000000..649fc7bb42c --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/browser.exp @@ -0,0 +1,33 @@ +# +# Check if we have a display +# +if {![info exists ::env(DISPLAY)]} { + untested "No DISPLAY -- skipping test" +} else { + + if {$tracelevel} { + strace $tracelevel + } + + # + # test console window + # + set prms_id 0 + set bug_id 0 + + set testfile "stack" + set binfile ${objdir}/${subdir}/${testfile} + set r [gdb_compile "${srcdir}/${subdir}/stack1.c ${srcdir}/${subdir}/stack2.c" "${binfile}" executable {debug}] + if { $r != "" } { + gdb_suppress_entire_file \ + "Testcase compile failed, so some tests in this file will automatically fail." + } + + # Start with a fresh gdbtk + gdb_exit + set results [gdbtk_start [file join $srcdir $subdir browser.test]] + set results [split $results \n] + + # Analyze results + gdbtk_analyze_results $results +} diff --git a/gdb/testsuite/gdb.gdbtk/browser.test b/gdb/testsuite/gdb.gdbtk/browser.test new file mode 100644 index 00000000000..832ad3633df --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/browser.test @@ -0,0 +1,683 @@ +# Copyright (C) 1998 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Keith Seitz (keiths@cygnus.com) + +# Read in the standard defs file + +if {![gdbtk_read_defs]} { + break +} + +global objdir test_ran +set _files(stupid_initializer) -100 + +##### ##### +# # +# Helper functions for this module # +# # +##### ##### + +# Set the search expression +proc set_regexp {exp} { + global browser + + $browser component filt_entry delete 0 end + $browser component filt_entry insert 0 $exp +} + +# Do the search +proc do_search {} { + global browser + $browser search + set m [$browser component func_box get 0 end] + + return $m +} + +# Set search to use regular expressions. +proc set_search_mode {val} { + global browser + pref set gdb/search/filter_mode $val + $browser component filt_type entryset $val +} + +# Highlight a file +proc select {filename} { + global browser _files + + if {[info exists _files($filename)]} { + $browser component file_box selection set $_files($filename) + } else { + set files [$browser component file_box get 0 end] + set i [lsearch $files $filename] + set _files($filename) $i + $browser component file_box selection set $i + } + $browser search +} + +proc select_all {} { + global browser + + $browser component file_all invoke + +} + +# clear all files +proc clear {} { + global browser + + $browser component file_box selection clear 0 end + $browser search +} + +##### ##### +# # +# BROWSER TESTS # +# # +##### ##### + +# Load the test executable +set file [file join $objdir stack] +gdb_cmd "file $file" + +# Open a browser +set browser [ManagedWin::open BrowserWin] + +# Test: browser-1.1 +# Desc: Check file listbox contents +gdbtk_test browser-1.1 {file listbox contents} { + set m [$browser component file_box get 0 end] + set f {} + if {[lsearch $m stack1.c] == -1} { + lappend f 0 + } else { + lappend f 1 + } + if {[lsearch $m stack2.c] == -1} { + lappend f 0 + } else { + lappend f 1 + } + + join $f \ +} {1 1} + +# Tests 2.* test starts with search mode. +# Test: browser-2.1 +# Desc: Check all files/all funcs +gdbtk_test browser-2.1 {all files/all funcs} { + set_search_mode "starts with" + set_regexp "" + select_all + set m [do_search] + set r 0 + foreach f {extern_func1_1 extern_func1_10 extern_func1_11 extern_func1_12 \ + extern_func1_13 extern_func1_14 extern_func1_15 extern_func1_2 \ + extern_func1_3 extern_func1_4 extern_func1_5 extern_func1_6 \ + extern_func1_7 extern_func1_8 extern_func1_9 func_1 \ + func_10 func_11 func_12 func_13 \ + func_14 func_15 func_2 func_3 \ + func_4 func_5 func_6 func_7 \ + func_8 func_9 main static_func_1 \ + static_func_10 static_func_11 static_func_12 static_func_13 \ + static_func_14 static_func_15 static_func_2 static_func_3 \ + static_func_4 static_func_5 static_func_6 static_func_7 \ + static_func_8 static_func_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {46} + +# Test: browser-2.2 +# Desc: Check all functions in stack1.c +gdbtk_test browser-2.2 {all functions in stack1.c} { + set_regexp "" + clear + select stack1.c + set m [do_search] + + set r 0 + foreach f {func_1 func_10 func_11 func_12 \ + func_13 func_14 func_15 func_2 \ + func_3 func_4 func_5 func_6 \ + func_7 func_8 func_9 main \ + static_func_1 static_func_10 static_func_11 static_func_12 \ + static_func_13 static_func_14 static_func_15 static_func_2 \ + static_func_3 static_func_4 static_func_5 static_func_6 \ + static_func_7 static_func_8 static_func_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {31} +if {$test_ran} { + clear +} + +# Test: browser-2.3 +# Desc: Check all functions in stack2.c +gdbtk_test browser-2.3 {all functions in stack2.c} { + set_regexp "" + clear + select stack2.c + set m [do_search] + + set r 0 + foreach f {extern_func1_1 extern_func1_10 extern_func1_11 \ + extern_func1_12 extern_func1_13 extern_func1_14 extern_func1_15 \ + extern_func1_2 extern_func1_3 extern_func1_4 extern_func1_5 \ + extern_func1_6 extern_func1_7 extern_func1_8 extern_func1_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {15} +if {$test_ran} { + clear +} + +# Test: browser-2.4 +# Desc: Check for all functions matching "func" - mode starts with +gdbtk_test browser-2.4 {all functions matching "func" - "mode starts with"} { + set_search_mode "starts with" + select_all + set_regexp func + do_search +} {func_1 func_10 func_11 func_12 func_13 func_14 func_15 func_2 func_3 func_4 func_5 func_6 func_7 func_8 func_9} + +# Test: browser-2.5 +# Desc: Check all functions matching "func" in stack1.c - mode starts with +gdbtk_test browser-2.5 {all functions matching "func" in stack1.c - "mode starts with"} { + set_search_mode "starts with" + set_regexp func + clear + select stack1.c + do_search +} {func_1 func_10 func_11 func_12 func_13 func_14 func_15 func_2 func_3 func_4 func_5 func_6 func_7 func_8 func_9} + +# Test: browser-2.6 +# Desc: Check all functions matching "funcs" in stack2.c - mode starts with +gdbtk_test browser-2.6 {all functions matching "func" in stack2.c - mode "starts with"} { + set_search_mode "starts with" + set_regexp func + clear + select stack2.c + do_search +} {} +if {$test_ran} { + clear +} + +# Test: browser-2.7 +# Desc: Check all functions matching "foobar" +gdbtk_test browser-2.7 {all functions matching "foobar"} { + set_search_mode "starts with" + select_all + set_regexp foobar + do_search +} {} + +# Test: browser-2.8 +# Desc: Check all functions matching "foobar" in stack1.c +gdbtk_test browser-2.8 {functions matching "foobar" in stack1.c} { + set_search_mode "starts with" + set_regexp foobar + clear + select stack1.c + do_search +} {} + +# Tests 3.* test "contains" search mode. +# Test: browser-3.1 +# Desc: Check all files/all funcs +gdbtk_test browser-3.1 {all files/all funcs} { + set_search_mode "contains" + set_regexp "" + select_all + set m [do_search] + set r 0 + foreach f {extern_func1_1 extern_func1_10 extern_func1_11 extern_func1_12 \ + extern_func1_13 extern_func1_14 extern_func1_15 extern_func1_2 \ + extern_func1_3 extern_func1_4 extern_func1_5 extern_func1_6 \ + extern_func1_7 extern_func1_8 extern_func1_9 func_1 \ + func_10 func_11 func_12 func_13 \ + func_14 func_15 func_2 func_3 \ + func_4 func_5 func_6 func_7 \ + func_8 func_9 main static_func_1 \ + static_func_10 static_func_11 static_func_12 static_func_13 \ + static_func_14 static_func_15 static_func_2 static_func_3 \ + static_func_4 static_func_5 static_func_6 static_func_7 \ + static_func_8 static_func_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {46} + +# Test: browser-3.2 +# Desc: Check all functions in stack1.c +gdbtk_test browser-3.2 {all functions in stack1.c} { + set_regexp "" + set_search_mode "contains" + clear + select stack1.c + set m [do_search] + + set r 0 + foreach f {func_1 func_10 func_11 func_12 \ + func_13 func_14 func_15 func_2 \ + func_3 func_4 func_5 func_6 \ + func_7 func_8 func_9 main \ + static_func_1 static_func_10 static_func_11 static_func_12 \ + static_func_13 static_func_14 static_func_15 static_func_2 \ + static_func_3 static_func_4 static_func_5 static_func_6 \ + static_func_7 static_func_8 static_func_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {31} + +if {$test_ran} { + clear +} + +# Test: browser-3.3 +# Desc: Check all functions in stack2.c +gdbtk_test browser-3.3 {all functions in stack2.c} { + set_regexp "" + set_search_mode "contains" + clear + select stack2.c + set m [do_search] + + set r 0 + foreach f {extern_func1_1 extern_func1_10 extern_func1_11 \ + extern_func1_12 extern_func1_13 extern_func1_14 extern_func1_15 \ + extern_func1_2 extern_func1_3 extern_func1_4 extern_func1_5 \ + extern_func1_6 extern_func1_7 extern_func1_8 extern_func1_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {15} +if {$test_ran} { + clear +} + +# Test: browser-3.4 +# Desc: Check for all functions matching "func" - mode contains +gdbtk_test browser-3.4 {all functions matching "func_1" - "mode contains"} { + set_search_mode "contains" + set_regexp "func_1" + select_all + do_search +} {func_1 func_10 func_11 func_12 func_13 func_14 func_15 static_func_1 static_func_10 static_func_11 static_func_12 static_func_13 static_func_14 static_func_15} + +# Test: browser-3.5 +# Desc: Check all functions matching "func_1" in stack1.c - mode contains +gdbtk_test browser-3.5 {all functions matching "func_1" in stack1.c - "mode contains"} { + set_search_mode "contains" + set_regexp "func_1" + clear + select stack1.c + do_search +} {func_1 func_10 func_11 func_12 func_13 func_14 func_15 static_func_1 static_func_10 static_func_11 static_func_12 static_func_13 static_func_14 static_func_15 } + +# Test: browser-3.6 +# Desc: Check all functions matching "func_1" in stack2.c - mode contains +gdbtk_test browser-3.6 {all functions matching "func" in stack2.c - mode "contains"} { + set_search_mode "contains" + set_regexp func_1 + clear + select stack2.c + do_search +} {} + +# Test: browser-3.7 +# Desc: Check all functions matching "foobar" +gdbtk_test browser-3.7 {all functions matching "foobar"} { + set_search_mode "contains" + select_all + set_regexp foobar + do_search +} {} + +# Test: browser-3.8 +# Desc: Check all functions matching "foobar" in stack1.c +gdbtk_test browser-3.8 {functions matching "foobar" in stack1.c} { + set_search_mode "contains" + set_regexp foobar + clear + select stack1.c + do_search +} {} + +# Tests 4.* test "ends with" search mode. +# Test: browser-4.1 +# Desc: Check all files/all funcs +gdbtk_test browser-4.1 {all files/all funcs} { + set_search_mode "ends with" + set_regexp "" + select_all + set m [do_search] + set r 0 + foreach f {extern_func1_1 extern_func1_10 extern_func1_11 extern_func1_12 \ + extern_func1_13 extern_func1_14 extern_func1_15 extern_func1_2 \ + extern_func1_3 extern_func1_4 extern_func1_5 extern_func1_6 \ + extern_func1_7 extern_func1_8 extern_func1_9 func_1 \ + func_10 func_11 func_12 func_13 \ + func_14 func_15 func_2 func_3 \ + func_4 func_5 func_6 func_7 \ + func_8 func_9 main static_func_1 \ + static_func_10 static_func_11 static_func_12 static_func_13 \ + static_func_14 static_func_15 static_func_2 static_func_3 \ + static_func_4 static_func_5 static_func_6 static_func_7 \ + static_func_8 static_func_9} { + if {[lsearch $m $f] > -1} { + incr r + } + } + + set r +} {46} + +# Test: browser-4.2 +# Desc: Check all functions in stack1.c +gdbtk_test browser-4.2 {all functions in stack1.c} { + set_regexp "" + set_search_mode "ends with" + clear + select stack1.c + set m [do_search] + + set r 0 + foreach f {func_1 func_10 func_11 func_12 \ + func_13 func_14 func_15 func_2 \ + func_3 func_4 func_5 func_6 \ + func_7 func_8 func_9 main \ + static_func_1 static_func_10 static_func_11 static_func_12 \ + static_func_13 static_func_14 static_func_15 static_func_2 \ + static_func_3 static_func_4 static_func_5 static_func_6 \ + static_func_7 static_func_8 static_func_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {31} + +if {$test_ran} { + clear +} + +# Test: browser-4.3 +# Desc: Check all functions in stack2.c +gdbtk_test browser-4.3 {all functions in stack2.c} { + set_regexp "" + set_search_mode "ends with" + clear + select stack2.c + set m [do_search] + + set r 0 + foreach f {extern_func1_1 extern_func1_10 extern_func1_11 \ + extern_func1_12 extern_func1_13 extern_func1_14 extern_func1_15 \ + extern_func1_2 extern_func1_3 extern_func1_4 extern_func1_5 \ + extern_func1_6 extern_func1_7 extern_func1_8 extern_func1_9} { + if {[lsearch $m $f] != -1} { + incr r + } + } + + set r +} {15} +if {$test_ran} { + clear +} + +# Test: browser-4.4 +# Desc: Check for all functions matching "func" - mode ends with +gdbtk_test browser-4.4 {all functions matching "func_1" - "mode ends with"} { + set_search_mode "ends with" + set_regexp "func_1" + select_all + do_search +} {func_1 func_10 func_11 func_12 func_13 func_14 func_15 static_func_1 static_func_10 static_func_11 static_func_12 static_func_13 static_func_14 static_func_15} + +# Test: browser-4.5 +# Desc: Check all functions matching "func_1" in stack1.c - mode ends with +gdbtk_test browser-4.5 {all functions matching "func_1" in stack1.c - "mode ends with"} { + set_search_mode "ends with" + set_regexp "func_1" + clear + select stack1.c + do_search +} {func_1 func_10 func_11 func_12 func_13 func_14 func_15 static_func_1 static_func_10 static_func_11 static_func_12 static_func_13 static_func_14 static_func_15 } +if {$test_ran} { + clear +} + +# Test: browser-4.6 +# Desc: Check all functions matching "func_1" in stack2.c - mode ends with +gdbtk_test browser-4.6 {all functions matching "func" in stack2.c - mode "ends with"} { + set_search_mode "ends with" + set_regexp func_1 + clear + select stack2.c + do_search +} {} + +# Test: browser-4.7 +# Desc: Check all functions matching "foobar" +gdbtk_test browser-4.7 {all functions matching "foobar"} { + set_search_mode "ends with" + select_all + set_regexp foobar + do_search +} {} + +# Test: browser-4.8 +# Desc: Check all functions matching "foobar" in stack1.c +gdbtk_test browser-4.8 {functions matching "foobar" in stack1.c} { + set_search_mode "ends with" + set_regexp foobar + clear + select stack1.c + do_search +} {} +if {$test_ran} { + clear +} + +# Test: browser-5.10 +# Desc: Check all functions matching regexp "func" +gdbtk_test browser-5.10 {all functions matching regexp "func"} { + set_search_mode "matches regexp" + set_regexp func + select_all + do_search +} {extern_func1_1 extern_func1_10 extern_func1_11 extern_func1_12 extern_func1_13 extern_func1_14 extern_func1_15 extern_func1_2 extern_func1_3 extern_func1_4 extern_func1_5 extern_func1_6 extern_func1_7 extern_func1_8 extern_func1_9 func_1 func_10 func_11 func_12 func_13 func_14 func_15 func_2 func_3 func_4 func_5 func_6 func_7 func_8 func_9 static_func_1 static_func_10 static_func_11 static_func_12 static_func_13 static_func_14 static_func_15 static_func_2 static_func_3 static_func_4 static_func_5 static_func_6 static_func_7 static_func_8 static_func_9} + +# Test: browser-5.11 +# Desc: Check all functions matching regexp "func" in stack1.c +gdbtk_test browser-5.11 {all functions matching regexp "func" in stack1.c} { + set_search_mode "matches regexp" + set_regexp func + clear + select stack1.c + do_search +} {func_1 func_10 func_11 func_12 func_13 func_14 func_15 func_2 func_3 func_4 func_5 func_6 func_7 func_8 func_9 static_func_1 static_func_10 static_func_11 static_func_12 static_func_13 static_func_14 static_func_15 static_func_2 static_func_3 static_func_4 static_func_5 static_func_6 static_func_7 static_func_8 static_func_9} + +# Test: browser-5.12 +# Desc: Check all functions matching regexp "func" in stack2.c +gdbtk_test browser-5.12 {all functions matching regexp "func" in stack2.c} { + set_regexp func + clear + select stack2.c + do_search +} {extern_func1_1 extern_func1_10 extern_func1_11 extern_func1_12 extern_func1_13 extern_func1_14 extern_func1_15 extern_func1_2 extern_func1_3 extern_func1_4 extern_func1_5 extern_func1_6 extern_func1_7 extern_func1_8 extern_func1_9} + +# Test: browser-5.13 +# Desc: Check all functions matching regexp "\_1$" +gdbtk_test browser-5.13 {all functions matching regexp "\_1$"} { + set_search_mode "matches regexp" + set_regexp {\_1$} + do_search +} {extern_func1_1 func_1 static_func_1} + +# Test: browser-5.14 +# Desc: Check all functions matching regexp "\_1$" in stack1.c +gdbtk_test browser-5.14 {all functions matching regexp "\_1$" in stack1.c} { + set_search_mode "matches regexp" + set_regexp {\_1$} + clear + select stack1.c + do_search +} {func_1 static_func_1} + +# Test: browser-5.15 +# Desc: Check all functions matching regexp "\_1$" in stack2.c +gdbtk_test browser-5.15 {all functions matching regexp "\_1$" in stack2.c} { + set_search_mode "matches regexp" + set_regexp {\_1$} + clear + select stack2.c + do_search +} {extern_func1_1} + +# Test: browser-5.16 +# Desc: Check all functions matching regexp "foobar" +gdbtk_test browser-5.16 {all functions matching regexp "foobar"} { + set_search_mode "matches regexp" + set_regexp foobar + select_all + do_search +} {} + +# Test: browser-5.17 +# Desc: Check all functions matching regexp "foobar" in stack1.c +gdbtk_test browser-5.17 {all functions matching regexp "foobar" in stack1.c} { + set_search_mode "matches regexp" + set_regexp foobar + clear + select stack1.c + do_search +} {} + + +# Test: browser-6.1 +# Desc: Check select button function +gdbtk_test browser-6.1 {select button - select all} { + clear + select_all + set m [$browser component file_box curselection] + + expr {[llength $m] >= 2} +} {1} + +# Test: browser-7.1 +# Desc: Toggle all bps on +gdbtk_test browser-7.1 {toggle_all_bp on} { + set_regexp {\_1$} + set_search_mode "matches regexp" + select_all + do_search + $browser component func_add_bp invoke + + set_regexp .* + set funcs [do_search] + + set bps {} + foreach f $funcs { + if {![catch {gdb_loc $f} ls]} { + if {[bp_exists $ls] != -1} { + lappend bps $f + } + } + } + + for {set i 0} {$i < 20} {incr i} { + catch {gdb_cmd "delete $i"} + } + + join [lsort $bps] +} {extern_func1_1 func_1 static_func_1} + +# Test: browser-7.2 +# Desc: Toggle all bps off +gdbtk_test browser-7.2 {toggle_all_bp off} { + set_regexp {\_1$} + set_search_mode "matches regexp" + select_all + do_search + $browser component func_add_bp invoke + + set_regexp .* + set funcs [do_search] + + # Turn off all static bps + set_regexp {\_1$} + do_search + $browser component func_remove_bp + set bps {} + foreach f $funcs { + if {![catch {gdb_loc $f} ls]} { + if {[bp_exists $ls] != -1} { + lappend bps $f + } + } + } + + for {set i 0} {$i < 20} {incr i} { + catch {gdb_cmd "delete $i"} + } + + join [lsort $bps] +} {extern_func1_1 func_1} + +# Test: browser-6.1 +# Desc: Check that search expressions are saved +gdbtk_test browser-6.1 {save last search expression} { + set_regexp hello + select_all + do_search + pref get gdb/search/last_symbol +} {hello} + +# +# Exit +# +gdbtk_test_done diff --git a/gdb/testsuite/gdb.gdbtk/c_variable.c b/gdb/testsuite/gdb.gdbtk/c_variable.c new file mode 100644 index 00000000000..461d5cee2fa --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/c_variable.c @@ -0,0 +1,296 @@ +struct _simple_struct { + int integer; + unsigned int unsigned_integer; + char character; + signed char signed_character; + char *char_ptr; + int array_of_10[10]; +}; + +typedef struct _simple_struct simpleton; + +simpleton global_simple; + +enum foo { + bar = 1, + baz +}; + +typedef enum foo efoo; + +union named_union +{ + int integer; + char *char_ptr; +}; + +typedef struct _struct_decl { + int integer; + char character; + char *char_ptr; + long long_int; + int **int_ptr_ptr; + long long_array[10]; + + void (*func_ptr) (void); + struct _struct_decl (*func_ptr_struct) (int, char *, long); + struct _struct_decl *(*func_ptr_ptr) (int, char *, long); + union { + int a; + char *b; + long c; + enum foo d; + } u1; + + struct { + union { + struct { + int d; + char e[10]; + int *(*func) (void); + efoo foo; + } u1s1; + + long f; + struct { + char array_ptr[2]; + int (*func) (int, char *); + } u1s2; + } u2; + + int g; + char h; + long i[10]; + } s2; +} weird_struct; + +struct _struct_n_pointer { + char ****char_ptr; + long ****long_ptr; + struct _struct_n_pointer *ptrs[3]; + struct _struct_n_pointer *next; +}; + +void do_locals_tests (void); +void do_block_tests (void); +void subroutine1 (int, long *); +void nothing (void); +void do_children_tests (void); +void do_special_tests (void); +void incr_a (int); + +void incr_a (int a) +{ + int b; + b = a; +} + +void +do_locals_tests () +{ + int linteger; + int *lpinteger; + char lcharacter; + char *lpcharacter; + long llong; + long *lplong; + float lfloat; + float *lpfloat; + double ldouble; + double *lpdouble; + struct _simple_struct lsimple; + struct _simple_struct *lpsimple; + void (*func) (void); + + /* Simple assignments */ + linteger = 1234; + lpinteger = &linteger; + lcharacter = 'a'; + lpcharacter = &lcharacter; + llong = 2121L; + lplong = &llong; + lfloat = 2.1; + lpfloat = &lfloat; + ldouble = 2.718281828459045; + lpdouble = &ldouble; + lsimple.integer = 1234; + lsimple.unsigned_integer = 255; + lsimple.character = 'a'; + lsimple.signed_character = 21; + lsimple.char_ptr = &lcharacter; + lpsimple = &lsimple; + func = nothing; + + /* Check pointers */ + linteger = 4321; + lcharacter = 'b'; + llong = 1212L; + lfloat = 1.2; + ldouble = 5.498548281828172; + lsimple.integer = 255; + lsimple.unsigned_integer = 4321; + lsimple.character = 'b'; + lsimple.signed_character = 0; + + subroutine1 (linteger, &llong); +} + +void +nothing () +{ +} + +void +subroutine1 (int i, long *l) +{ + global_simple.integer = i + 3; + i = 212; + *l = 12; +} + +void +do_block_tests () +{ + int cb = 12; + + { + int foo; + foo = 123; + { + int foo2; + foo2 = 123; + { + int foo; + foo = 321; + } + foo2 = 0; + } + foo = 0; + } + + cb = 21; +} + +void +do_children_tests (void) +{ + weird_struct *weird; + struct _struct_n_pointer *psnp; + struct _struct_n_pointer snp0, snp1, snp2; + char a0, *a1, **a2, ***a3; + char b0, *b1, **b2, ***b3; + char c0, *c1, **c2, ***c3; + long z0, *z1, **z2, ***z3; + long y0, *y1, **y2, ***y3; + long x0, *x1, **x2, ***x3; + int *foo; + int bar; + + struct _struct_decl struct_declarations; + weird = &struct_declarations; + + struct_declarations.integer = 123; + weird->char_ptr = "hello"; + bar = 2121; + foo = &bar; + struct_declarations.int_ptr_ptr = &foo; + weird->long_array[0] = 1234; + struct_declarations.long_array[1] = 2345; + weird->long_array[2] = 3456; + struct_declarations.long_array[3] = 4567; + weird->long_array[4] = 5678; + struct_declarations.long_array[5] = 6789; + weird->long_array[6] = 7890; + struct_declarations.long_array[7] = 8901; + weird->long_array[8] = 9012; + struct_declarations.long_array[9] = 1234; + + weird->func_ptr = nothing; + + /* Struct/pointer/array tests */ + a0 = '0'; + a1 = &a0; + a2 = &a1; + a3 = &a2; + b0 = '1'; + b1 = &b0; + b2 = &b1; + b3 = &b2; + c0 = '2'; + c1 = &c0; + c2 = &c1; + c3 = &c2; + z0 = 0xdead + 0; + z1 = &z0; + z2 = &z1; + z3 = &z2; + y0 = 0xdead + 1; + y1 = &y0; + y2 = &y1; + y3 = &y2; + x0 = 0xdead + 2; + x1 = &x0; + x2 = &x1; + x3 = &x2; + snp0.char_ptr = &a3; + snp0.long_ptr = &z3; + snp0.ptrs[0] = &snp0; + snp0.ptrs[1] = &snp1; + snp0.ptrs[2] = &snp2; + snp0.next = &snp1; + snp1.char_ptr = &b3; + snp1.long_ptr = &y3; + snp1.ptrs[0] = &snp0; + snp1.ptrs[1] = &snp1; + snp1.ptrs[2] = &snp2; + snp1.next = &snp2; + snp2.char_ptr = &c3; + snp2.long_ptr = &x3; + snp2.ptrs[0] = &snp0; + snp2.ptrs[1] = &snp1; + snp2.ptrs[2] = &snp2; + snp2.next = 0x0; + psnp = &snp0; + snp0.char_ptr = &b3; + snp1.char_ptr = &c3; + snp2.char_ptr = &a3; + snp0.long_ptr = &y3; + snp1.long_ptr = &x3; + snp2.long_ptr = &z3; +} + +void +do_special_tests (void) +{ + union named_union u; + union { + int a; + char b; + long c; + } anonu; + struct _simple_struct s; + struct { + int a; + char b; + long c; + } anons; + enum foo e; + enum { A, B, C } anone; + int array[21]; + int a; + + a = 1; + incr_a(2); +} + +int +main (int argc, char *argv []) +{ + do_locals_tests (); + do_block_tests (); + do_children_tests (); + do_special_tests (); + exit (0); +} + + diff --git a/gdb/testsuite/gdb.gdbtk/c_variable.exp b/gdb/testsuite/gdb.gdbtk/c_variable.exp new file mode 100644 index 00000000000..8452034fe83 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/c_variable.exp @@ -0,0 +1,34 @@ +# +# Check if we have a display +# +if {![info exists ::env(DISPLAY)]} { + untested "No DISPLAY -- skipping test" +} else { + + if {$tracelevel} { + strace $tracelevel + } + + # + # test variable API + # + set prms_id 0 + set bug_id 0 + + set testfile "c_variable" + set srcfile ${testfile}.c + set binfile ${objdir}/${subdir}/${testfile} + set r [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] + if { $r != "" } { + gdb_suppress_entire_file \ + "Testcase compile failed, so some tests in this file will automatically fail." + } + + # Start with a fresh gdbtk + gdb_exit + set results [gdbtk_start [file join $srcdir $subdir ${testfile}.test]] + set results [split $results \n] + + # Analyze results + gdbtk_analyze_results $results +} diff --git a/gdb/testsuite/gdb.gdbtk/c_variable.test b/gdb/testsuite/gdb.gdbtk/c_variable.test new file mode 100644 index 00000000000..098c9240ea4 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/c_variable.test @@ -0,0 +1,2066 @@ +# Copyright (C) 1998 Cygnus Solutions +# +# This Program Is Free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Keith Seitz (keiths@cygnus.com) + +# Read in the standard defs file +if {![gdbtk_read_defs]} { + break +} + +global objdir test_ran +global tcl_platform + +# Load in a file +if {$tcl_platform(platform) == "windows"} { + set program [file join $objdir c_variable.exe] +} else { + set program [file join $objdir c_variable] +} + +# This isn't a test case, since if this fails, we're hosed. +if {[catch {gdb_cmd "file $program"} t]} { + # an error occured loading the file + gdbtk_test_error "loading \"$program\": $t" +} + +# The variables that are created are stored in an array called "var". + +# proc to tell us which of the variables are changed/out of scope +proc check_update {} { + global var + + set changed {} + set unchanged {} + set out {} + #FIXME: Should get a list of root variables instead of using the array + foreach ind [array names var] { + set changed [concat $changed [$var($ind) update]] + } + + foreach ind [array names var] { + set ix [lsearch -exact $changed $var($ind)] + if {$ix < 0} { + lappend unchanged $var($ind) + } + } + + return [list $changed $unchanged $out] +} + +# proc to create a variable +proc create_variable {expr} { + global var + + set err [catch {gdb_variable create "$expr" -expr $expr} v] + if {!$err} { + set var($expr) $v + } + + return $err +} + +# proc to get the children +# Children are stored in the global "var" as +# PARENT.child. So for struct _foo {int a; int b} bar;, +# the children returned are {a b} and var(bar.a) and var(bar.b) +# map the actual objects to their names. +proc get_children {parent} { + global var + + set kiddies [$var($parent) children] + set children {} + foreach child $kiddies { + set name [lindex [split $child .] end] + lappend children $name + set var($parent.$name) $child + } + + return $children +} + +proc delete_variable {varname} { + global var + + if {[info exists var($varname)]} { + # This has to be caught, since deleting a parent + # will erase all children. + $var($varname) delete + set vars [array names var $varname*] + foreach v $vars { + if {[info exists var($v)]} { + unset var($v) + } + } + } +} + +# Compare the values of variable V in format FMT +# with gdb's value. +proc value {v fmt} { + global var + global _test + + set value [$var($v) value] + set gdb [gdb_cmd "output/$fmt $v"] + if {$value == $gdb} { + set result ok + } else { + set result $v + puts $_test(logfile) "output/$fmt $v" + puts $_test(logfile) "gdbtk: $value <> gdb: $gdb" + } + + return $result +} + +proc delete_all_variables {} { + global var + + foreach variable [array names var] { + delete_variable $variable + } +} + +proc editable_variables {} { + global var + + set yes {} + set no {} + foreach name [array names var] { + if {[$var($name) editable]} { + lappend yes $name + } else { + lappend no $name + } + } + + return [list $yes $no] +} + + +##### ##### +# # +# Variable Creation tests # +# # +##### ##### + +# Test: c_variable-1.1 +# Desc: Create global variable +gdbtk_test c_variable-1.1 {create global variable} { + create_variable global_simple +} {0} + +# Test: c_variable-1.2 +# Desc: Create non-existent variable +gdbtk_test c_variable-1.2 {create non-existent variable} { + create_variable bogus_unknown_variable +} {1} + +# Test: c_variable-1.3 +# Desc: Create out of scope variable +gdbtk_test c_variable-1.3 {create out of scope variable} { + create_variable argc +} {1} + +## FIXME: natives only +# Break in main and run +gdb_cmd "break do_locals_tests" +gdb_cmd "run" + +# Test: c_variable-1.4 +# Desc: create local variables +gdbtk_test c_variable-1.4 {create local variables} { + set results {} + foreach v {linteger lpinteger lcharacter lpcharacter llong lplong lfloat lpfloat ldouble lpdouble lsimple lpsimple func} { + lappend results [create_variable $v] + } + set results +} {0 0 0 0 0 0 0 0 0 0 0 0 0} + +# Test: c_variable-1.5 +# Desc: create lsimple.character +gdbtk_test c_variable-1.5 {create lsimple.character} { + create_variable lsimple.character +} {0} + +# Test: c_variable-1.6 +# Desc: create lpsimple->integer +gdbtk_test c_variable-1.6 {create lpsimple->integer} { + create_variable lpsimple->integer +} {0} + +# Test: c_variable-1.7 +# Desc: ceate lsimple.integer +gdbtk_test c_variable-1.7 {create lsimple.integer} { + create_variable lsimple.integer +} {0} + +# Test: c_variable-1.8 +# Desc: names of editable variables +gdbtk_test c_variable-1.8 {names of editable variables} { + editable_variables +} {{lsimple.character lsimple.integer lpsimple lcharacter lpcharacter linteger lpinteger lfloat lpfloat func llong lplong lpsimple->integer ldouble lpdouble} {lsimple global_simple}} + +# Test: c_variable-1.9 +# Desc: create type name +# Type names (like int, long, etc..) are all proper expressions to gdb. +# make sure variable code does not allow users to create variables, though. +gdbtk_test c_variable-1.9 {create type name} { + create_variable int +} {1} + +##### ##### +# # +# Value changed tests # +# # +##### ##### + +# Test: c_variable-2.1 +# Desc: check whether values changed at do_block_tests +gdbtk_test c_variable-2.1 {check whether values changed at do_block_tests} { + check_update +} {{} {lsimple.character lsimple.integer lpsimple lsimple lcharacter lpcharacter global_simple linteger lpinteger lfloat lpfloat func llong lplong lpsimple->integer ldouble lpdouble} {}} + +# Step over "linteger = 1234;" +gdb_cmd "step" + +# Test: c_variable-2.2 +# Desc: check whether only linteger changed values +gdbtk_test c_variable-2.2 {check whether only linteger changed values} { + check_update +} {linteger {lsimple.character lsimple.integer lpsimple lsimple lcharacter lpcharacter global_simple lpinteger lfloat lpfloat func llong lplong lpsimple->integer ldouble lpdouble} {}} + +# Step over "lpinteger = &linteger;" +gdb_cmd "step" + +# Test: c_variable-2.3 +# Desc: check whether only lpinteger changed +gdbtk_test c_variable-2.3 {check whether only lpinteger changed} { + check_update +} {lpinteger {lsimple.character lsimple.integer lpsimple lsimple lcharacter lpcharacter global_simple linteger lfloat lpfloat func llong lplong lpsimple->integer ldouble lpdouble} {}} + +# Step over "lcharacter = 'a';" +gdb_cmd "step" + +# Test: c_variable-2.4 +# Desc: check whether only lcharacter changed +gdbtk_test c_variable-2.4 {check whether only lcharacter changed} { + check_update +} {lcharacter {lsimple.character lsimple.integer lpsimple lsimple lpcharacter global_simple linteger lpinteger lfloat lpfloat func llong lplong lpsimple->integer ldouble lpdouble} {}} + +# Step over "lpcharacter = &lcharacter;" +gdb_cmd "step" + +# Test: c_variable-2.5 +# Desc: check whether only lpcharacter changed +gdbtk_test c_variable-2.5 {check whether only lpcharacter changed} { + check_update +} {lpcharacter {lsimple.character lsimple.integer lpsimple lsimple lcharacter global_simple linteger lpinteger lfloat lpfloat func llong lplong lpsimple->integer ldouble lpdouble} {}} + +# Step over: +# llong = 2121L; +# lplong = &llong; +# lfloat = 2.1; +# lpfloat = &lfloat; +# ldouble = 2.718281828459045; +# lpdouble = &ldouble; +# lsimple.integer = 1234; +# lsimple.unsigned_integer = 255; +# lsimple.character = 'a'; +for {set i 0} {$i < 9} {incr i} { + gdb_cmd "step" +} + +# Test: c_variable-2.6 +# Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer, +# lsimple.unsigned_character lsimple.integer lsimple.character changed +gdbtk_test c_variable-2.6 {check whether llong -- lsimple.character changed} { + check_update +} {{lsimple.character lsimple.integer lfloat lpfloat llong lplong ldouble lpdouble} {lpsimple lsimple lcharacter lpcharacter global_simple linteger lpinteger func lpsimple->integer} {}} + +# Step over: +# lsimple.signed_character = 21; +# lsimple.char_ptr = &lcharacter; +# lpsimple = &lsimple; +# func = nothing; +for {set i 0} {$i < 4} {incr i} { + gdb_cmd "step" +} + +# Test: c_variable-2.7 +# Desc: check whether lsimple.signed_character, lsimple.char_ptr, lpsimple, func changed +gdbtk_test c_variable-2.7 {check whether lsimple.signed_character, lsimple.char_ptr, lpsimple, func changed} { + check_update +} {{lpsimple func lpsimple->integer} {lsimple.character lsimple.integer lsimple lcharacter lpcharacter global_simple linteger lpinteger lfloat lpfloat llong lplong ldouble lpdouble} {}} + +# Step over +# linteger = 4321; +# lcharacter = 'b'; +# llong = 1212L; +# lfloat = 1.2; +# ldouble = 5.498548281828172; +# lsimple.integer = 255; +# lsimple.unsigned_integer = 4321; +# lsimple.character = 'b'; +for {set i 0} {$i < 8} {incr i} { + gdb_cmd "step" +} + +# Test: c_variable-2.8 +# Desc: check whether linteger, lcharacter, llong, lfoat, ldouble, lsimple.integer, +# lpsimple.integer lsimple.character changed +# Note: this test also checks that lpsimple->integer and lsimple.integer have +# changed (they are the same) +gdbtk_test c_variable-2.8 {check whether linteger -- lsimple.integer changed} { + check_update +} {{lsimple.character lsimple.integer lcharacter linteger lfloat llong lpsimple->integer ldouble} {lpsimple lsimple lpcharacter global_simple lpinteger lpfloat func lplong lpdouble} {}} + +gdb_cmd "break subroutine1" +gdb_cmd "continue" + +# Test: c_variable-2.9 +# Desc: stop in subroutine1 +gdbtk_test c_variable-2.9 {stop in subroutine1} { + lindex [gdb_loc] 1 +} {subroutine1} + +# Test: c_variable-2.10 +# Desc: create variable for locals i,l in subroutine1 +gdbtk_test c_variable-2.10 {create variable for locals i,l in subroutine1} { + set r [create_variable i] + lappend r [create_variable l] +} {0 0} + +# Test: c_variable-2.11 +# Desc: create do_locals_tests local in subroutine1 +gdbtk_test c_variable-2.11 {create do_locals_tests local in subroutine1} { + create_variable linteger +} {1} + +gdb_cmd "step" + +# Test: c_variable-2.12 +# Desc: change global_simple.integer +# Note: This also tests whether we are reporting changes in structs properly. +# gdb normally would say that global_simple has changed, but we +# special case that, since it is not what a human expects to see. +gdbtk_test c_variable-2.12 {change global_simple.integer} { + check_update +} {{} {lsimple.character lsimple.integer lpsimple lsimple i lcharacter lpcharacter global_simple linteger lpinteger lfloat lpfloat l func llong lplong lpsimple->integer ldouble lpdouble} {}} + +gdb_cmd "step" + +# Test: c_variable-2.13 +# Desc: change subroutine1 local i +gdbtk_test c_variable-2.13 {change subroutine1 local i} { + check_update +} {i {lsimple.character lsimple.integer lpsimple lsimple lcharacter lpcharacter global_simple linteger lpinteger lfloat lpfloat l func llong lplong lpsimple->integer ldouble lpdouble} {}} + +gdb_cmd "step" + +# Test: c_variable-2.14 +# Desc: change do_locals_tests local llong +gdbtk_test c_variable-2.14 {change do_locals_tests local llong} { + check_update +} {llong {lsimple.character lsimple.integer lpsimple lsimple i lcharacter lpcharacter global_simple linteger lpinteger lfloat lpfloat l func lplong lpsimple->integer ldouble lpdouble} {}} + +gdb_cmd "next" + +# Test: c_variable-2.15 +# Desc: check for out of scope subroutine1 locals +gdbtk_test *c_variable-2.15 {check for out of scope subroutine1 locals (ops, we don't have a out-of-scope list yet)} { + check_update +} {{} {lsimple.character lsimple.integer lpsimple lsimple lcharacter lpcharacter global_simple linteger lpinteger lfloat lpfloat func llong lplong lpsimple->integer ldouble lpdouble} {i l}} + +# Test: c_variable-2.16 +# Desc: names of all editable variables +gdbtk_test c_variable-2.16 {names of all editable variables} { + editable_variables +} {{lsimple.character lsimple.integer lpsimple i lcharacter lpcharacter linteger lpinteger lfloat lpfloat l func llong lplong lpsimple->integer ldouble lpdouble} {lsimple global_simple}} + +# Done with locals/globals tests. Erase all variables +delete_all_variables + +##### ##### +# # +# Block tests # +# # +##### ##### +gdb_cmd "break do_block_tests" +gdb_cmd "continue" + +# Test: c_variable-3.1 +# Desc: stop in do_block_tests +gdbtk_test c_variable-3.1 {stop in do_block_tests} { + lindex [gdb_loc] 1 +} {do_block_tests} + +# Test: c_variable-3.2 +# Desc: create cb and foo +gdbtk_test c_variable-3.2 {create cb and foo} { + set r [create_variable cb] + lappend r [create_variable foo] +} {0 1} + +# step to "foo = 123;" +gdb_cmd "step" + +# Be paranoid and assume 3.2 created foo +delete_variable foo + +# Test: c_variable-3.3 +# Desc: create foo +gdbtk_test c_variable-3.3 {create foo} { + create_variable foo +} {0} + +# step to "foo2 = 123;" +gdb_cmd "step" + +# Test: c_variable-3.4 +# Desc: check foo, cb changed +gdbtk_test c_variable-3.4 {check foo,cb changed} { + check_update +} {{foo cb} {} {}} + +# step to "foo = 321;" +gdb_cmd "step" + +# Test: c_variable-3.5 +# Desc: create inner block foo +gdbtk_test c_variable-3.5 {create inner block foo} { + global var + set err [catch {gdb_variable create inner_foo -expr foo} v] + if {!$err} { + set var(inner_foo) $v + } + + set err +} {0} + +# step to "foo2 = 0;" +gdb_cmd "step" + +# Test: c_variable-3.6 +# Desc: create foo2 +gdbtk_test c_variable-3.6 {create foo2} { + create_variable foo2 +} {0} + +# Test: c_variable-3.7 +# Desc: check that outer foo in scope and inner foo out of scope +# Note: also a known gdb problem +gdbtk_test *c_variable-3.7 {check that outer foo in scope and inner foo out of scope (known gdb problem)} { + check_update +} {{} {foo2 foo cb} inner_foo} + +delete_variable inner_foo + +# step to "foo = 0;" +gdb_cmd "step" + +# Test: c_variable-3.8 +# Desc: check that foo2 out of scope +gdbtk_test *c_variable-3.8 {check that foo2 out of scope (known gdb problem} { + check_update +} {{} {foo cb} foo2} + +# step to "cb = 21;" +gdb_cmd "step" + +# Test: c_variable-3.9 +# Desc: check that only cb is in scope +gdbtk_test *c_variable-3.9 {check that only cb is in scope (known gdb problem)} { + check_update +} {{} cb {foo2 foo}} + +# Test: c_variable-3.10 +# Desc: names of editable variables +gdbtk_test c_variable-3.10 {names of editable variables} { + editable_variables +} {{foo cb foo2} {}} + +# Done with block tests +delete_all_variables + +##### ##### +# # +# children tests # +# # +##### ##### + +gdb_cmd "break do_children_tests" +gdb_cmd "continue" + +# Test: c_variable-4.1 +# Desc: stopped in do_children_tests +gdbtk_test c_variable-4.1 {stopped in do_children_tests} { + lindex [gdb_loc] 1 +} {do_children_tests} + +# Test: c_variable-4.2 +# Desc: create variable "struct_declarations" +gdbtk_test c_variable-4.2 {create variable "struct_declarations"} { + create_variable struct_declarations +} {0} + +# Test: c_variable-4.3 +# Desc: children of struct_declarations +gdbtk_test c_variable-4.3 {children of struct_declarations} { + get_children struct_declarations +} {integer character char_ptr long_int int_ptr_ptr long_array func_ptr func_ptr_struct func_ptr_ptr u1 s2} + +# Test: c_variable-4.4 +# Desc: number of children of struct_declarations +gdbtk_test c_variable-4.4 {number of children of struct_declarations} { + $var(struct_declarations) numChildren +} {11} + +# Test: c_variable-4.5 +# Desc: children of struct_declarations.integer +gdbtk_test c_variable-4.5 {children of struct_declarations.integer} { + get_children struct_declarations.integer +} {} + +# Test: c_variable-4.6 +# Desc: number of children of struct_declarations.integer +gdbtk_test c_variable-4.6 {number of children of struct_declarations.integer} { + $var(struct_declarations.integer) numChildren +} {0} + +# Test: c_variable-4.7 +# Desc: children of struct_declarations.character +gdbtk_test c_variable-4.7 {children of struct_declarations.character} { + get_children struct_declarations.character +} {} + +# Test: c_variable-4.8 +# Desc: number of children of struct_declarations.character +gdbtk_test c_variable-4.8 {number of children of struct_declarations.character} { + $var(struct_declarations.character) numChildren +} {0} + +# Test: c_variable-4.9 +# Desc: children of struct_declarations.char_ptr +gdbtk_test c_variable-4.9 {children of struct_declarations.char_ptr} { + get_children struct_declarations.char_ptr +} {} + +# Test: c_variable-4.10 +# Desc: number of children of struct_declarations.char_ptr +gdbtk_test c_variable-4.10 {number of children of struct_declarations.char_ptr} { + $var(struct_declarations.char_ptr) numChildren +} {0} + +# Test: c_variable-4.11 +# Desc: children of struct_declarations.long_int +gdbtk_test c_variable-4.11 {children of struct_declarations.long_int} { + + get_children struct_declarations.long_int +} {} + +# Test: c_variable-4.12 +# Desc: number of children of struct_declarations.long_int +gdbtk_test c_variable-4.12 {number of children of struct_declarations.long_int} { + $var(struct_declarations.long_int) numChildren +} {0} + +# Test: c_variable-4.13 +# Desc: children of int_ptr_ptr +gdbtk_test c_variable-4.13 {children of int_ptr_ptr} { + get_children struct_declarations.int_ptr_ptr +} {*int_ptr_ptr} + +# Test: c_variable-4.14 +# Desc: number of children of int_ptr_ptr +gdbtk_test c_variable-4.14 {number of children of int_ptr_ptr} { + $var(struct_declarations.int_ptr_ptr) numChildren +} {1} + +# Test: c_variable-4.15 +# Desc: children of struct_declarations.long_array +gdbtk_test c_variable-4.15 {children of struct_declarations.long_array} { + get_children struct_declarations.long_array +} {0 1 2 3 4 5 6 7 8 9} + +# Test: c_variable-4.16 +# Desc: number of children of struct_declarations.long_array +gdbtk_test c_variable-4.16 {number of children of struct_declarations.long_array} { + $var(struct_declarations.long_array) numChildren +} {10} + +# Test: c_variable-4.17 +# Desc: children of struct_declarations.func_ptr +gdbtk_test c_variable-4.17 {children of struct_declarations.func_ptr} { + get_children struct_declarations.func_ptr +} {} + +# Test: c_variable-4.18 +# Desc: number of children of struct_declarations.func_ptr +gdbtk_test c_variable-4.18 {number of children of struct_declarations.func_ptr} { + $var(struct_declarations.func_ptr) numChildren +} {0} + +# Test: c_variable-4.19 +# Desc: children of struct_declarations.func_ptr_struct +gdbtk_test c_variable-4.19 {children of struct_declarations.func_ptr_struct} { + get_children struct_declarations.func_ptr_struct +} {} + +# Test: c_variable-4.20 +# Desc: number of children of struct_declarations.func_ptr_struct +gdbtk_test c_variable-4.20 {number of children of struct_declarations.func_ptr_struct} { + $var(struct_declarations.func_ptr_struct) numChildren +} {0} + +# Test: c_variable-4.21 +# Desc: children of struct_declarations.func_ptr_ptr +gdbtk_test c_variable-4.21 {children of struct_declarations.func_ptr_ptr} { + get_children struct_declarations.func_ptr_ptr +} {} + +# Test: c_variable-4.22 +# Desc: number of children of struct_declarations.func_ptr_ptr +gdbtk_test c_variable-4.22 {number of children of struct_declarations.func_ptr_ptr} { + $var(struct_declarations.func_ptr_ptr) numChildren +} {0} + +# Test: c_variable-4.23 +# Desc: children of struct_declarations.u1 +gdbtk_test c_variable-4.23 {children of struct_declarations.u1} { + get_children struct_declarations.u1 +} {a b c d} + +# Test: c_variable-4.24 +# Desc: number of children of struct_declarations.u1 +gdbtk_test c_variable-4.24 {number of children of struct_declarations.u1} { + $var(struct_declarations.u1) numChildren +} {4} + +# Test: c_variable-4.25 +# Desc: children of struct_declarations.s2 +gdbtk_test c_variable-4.25 {children of struct_declarations.s2} { + get_children struct_declarations.s2 +} {u2 g h i} + +# Test: c_variable-4.26 +# Desc: number of children of struct_declarations.s2 +gdbtk_test c_variable-4.26 {number of children of struct_declarations.s2} { + $var(struct_declarations.s2) numChildren +} {4} + +# Test: c_variable-4.27 +# Desc: children of struct_declarations.long_array.1 +gdbtk_test c_variable-4.27 {children of struct_declarations.long_array.1} { + get_children struct_declarations.long_array.1 +} {} + +# Test: c_variable-4.28 +# Desc: number of children of struct_declarations.long_array.1 +gdbtk_test c_variable-4.28 {number of children of struct_declarations.long_array.1} { + $var(struct_declarations.long_array.1) numChildren +} {0} + +# Test: c_variable-4.29 +# Desc: children of struct_declarations.long_array.2 +gdbtk_test c_variable-4.29 {children of struct_declarations.long_array.2} { + get_children struct_declarations.long_array.2 +} {} + +# Test: c_variable-4.30 +# Desc: number of children of struct_declarations.long_array.2 +gdbtk_test c_variable-4.30 {number of children of struct_declarations.long_array.2} { + $var(struct_declarations.long_array.2) numChildren +} {0} + +# Test: c_variable-4.31 +# Desc: children of struct_declarations.long_array.3 +gdbtk_test c_variable-4.31 {children of struct_declarations.long_array.3} { + get_children struct_declarations.long_array.3 +} {} + +# Test: c_variable-4.32 +# Desc: number of children of struct_declarations.long_array.3 +gdbtk_test c_variable-4.32 {number of children of struct_declarations.long_array.3} { + $var(struct_declarations.long_array.3) numChildren +} {0} + +# Test: c_variable-4.33 +# Desc: children of struct_declarations.long_array.4 +gdbtk_test c_variable-4.33 {children of struct_declarations.long_array.4} { + get_children struct_declarations.long_array.4 +} {} + +# Test: c_variable-4.34 +# Desc: number of children of struct_declarations.long_array.4 +gdbtk_test c_variable-4.34 {number of children of struct_declarations.long_array.4} { + $var(struct_declarations.long_array.4) numChildren +} {0} + +# Test: c_variable-4.35 +# Desc: children of struct_declarations.long_array.5 +gdbtk_test c_variable-4.35 {children of struct_declarations.long_array.5} { + get_children struct_declarations.long_array.5 +} {} + +# Test: c_variable-4.36 +# Desc: number of children of struct_declarations.long_array.5 +gdbtk_test c_variable-4.36 {number of children of struct_declarations.long_array.5} { + $var(struct_declarations.long_array.5) numChildren +} {0} + +# Test: c_variable-4.37 +# Desc: children of struct_declarations.long_array.6 +gdbtk_test c_variable-4.37 {children of struct_declarations.long_array.6} { + get_children struct_declarations.long_array.6 +} {} + +# Test: c_variable-4.38 +# Desc: number of children of struct_declarations.long_array.6 +gdbtk_test c_variable-4.38 {number of children of struct_declarations.long_array.6} { + $var(struct_declarations.long_array.6) numChildren +} {0} + +# Test: c_variable-4.39 +# Desc: children of struct_declarations.long_array.7 +gdbtk_test c_variable-4.39 {children of struct_declarations.long_array.7} { + get_children struct_declarations.long_array.7 +} {} + +# Test: c_variable-4.40 +# Desc: number of children of struct_declarations.long_array.7 +gdbtk_test c_variable-4.40 {number of children of struct_declarations.long_array.7} { + $var(struct_declarations.long_array.7) numChildren +} {0} + +# Test: c_variable-4.41 +# Desc: children of struct_declarations.long_array.8 +gdbtk_test c_variable-4.41 {children of struct_declarations.long_array.8} { + get_children struct_declarations.long_array.8 +} {} + +# Test: c_variable-4.42 +# Desc: number of children of struct_declarations.long_array.8 +gdbtk_test c_variable-4.42 {number of children of struct_declarations.long_array.8} { + $var(struct_declarations.long_array.8) numChildren +} {0} + +# Test: c_variable-4.43 +# Desc: children of struct_declarations.long_array.9 +gdbtk_test c_variable-4.43 {children of struct_declarations.long_array.9} { + get_children struct_declarations.long_array.9 +} {} + +# Test: c_variable-4.44 +# Desc: number of children of struct_declarations.long_array.9 +gdbtk_test c_variable-4.44 {number of children of struct_declarations.long_array.9} { + $var(struct_declarations.long_array.9) numChildren +} {0} + +# Test: c_variable-4.45 +# Desc: children of struct_declarations.u1.a +gdbtk_test c_variable-4.45 {children of struct_declarations.u1.a} { + get_children struct_declarations.u1.a +} {} + +# Test: c_variable-4.46 +# Desc: number of children of struct_declarations.u1.a +gdbtk_test c_variable-4.46 {number of children of struct_declarations.u1.a} { + $var(struct_declarations.u1.a) numChildren +} {0} + +# Test: c_variable-4.47 +# Desc: children of struct_declarations.u1.b +gdbtk_test c_variable-4.47 {children of struct_declarations.u1.b} { + get_children struct_declarations.u1.b +} {} + +# Test: c_variable-4.48 +# Desc: number of children of struct_declarations.u1.b +gdbtk_test c_variable-4.48 {number of children of struct_declarations.u1.b} { + $var(struct_declarations.u1.b) numChildren +} {0} + +# Test: c_variable-4.49 +# Desc: children of struct_declarations.u1.c +gdbtk_test c_variable-4.49 {children of struct_declarations.u1.c} { + get_children struct_declarations.u1.c +} {} + +# Test: c_variable-4.50 +# Desc: number of children of struct_declarations.u1.c +gdbtk_test c_variable-4.50 {number of children of struct_declarations.u1.c} { + $var(struct_declarations.u1.c) numChildren +} {0} + +# Test: c_variable-4.51 +# Desc: children of struct_declarations.u1.d +gdbtk_test c_variable-4.51 {children of struct_declarations.u1.d} { + get_children struct_declarations.u1.d +} {} + +# Test: c_variable-4.52 +# Desc: number of children of struct_declarations.u1.d +gdbtk_test c_variable-4.52 {number of children of struct_declarations.u1.d} { + $var(struct_declarations.u1.d) numChildren +} {0} + +# Test: c_variable-4.53 +# Desc: children of struct_declarations.s2.u2 +gdbtk_test c_variable-4.53 {children of struct_declarations.s2.u2} { + get_children struct_declarations.s2.u2 +} {u1s1 f u1s2} + +# Test: c_variable-4.54 +# Desc: number of children of struct_declarations.s2.u2 +gdbtk_test c_variable-4.54 {number of children of struct_declarations.s2.u2} { + $var(struct_declarations.s2.u2) numChildren +} {3} + +# Test: c_variable-4.55 +# Desc: children of struct_declarations.s2.g +gdbtk_test c_variable-4.55 {children of struct_declarations.s2.g} { + get_children struct_declarations.s2.g +} {} + +# Test: c_variable-4.56 +# Desc: number of children of struct_declarations.s2.g +gdbtk_test c_variable-4.56 {number of children of struct_declarations.s2.g} { + $var(struct_declarations.s2.g) numChildren +} {0} + +# Test: c_variable-4.57 +# Desc: children of struct_declarations.s2.h +gdbtk_test c_variable-4.57 {children of struct_declarations.s2.h} { + get_children struct_declarations.s2.h +} {} + +# Test: c_variable-4.58 +# Desc: number of children of struct_declarations.s2.h +gdbtk_test c_variable-4.58 {number of children of struct_declarations.s2.h} { + $var(struct_declarations.s2.h) numChildren +} {0} + +# Test: c_variable-4.59 +# Desc: children of struct_declarations.s2.i +gdbtk_test c_variable-4.59 {children of struct_declarations.s2.i} { + get_children struct_declarations.s2.i +} {0 1 2 3 4 5 6 7 8 9} + +# Test: c_variable-4.60 +# Desc: number of children of struct_declarations.s2.i +gdbtk_test c_variable-4.60 {number of children of struct_declarations.s2.i} { + $var(struct_declarations.s2.i) numChildren +} {10} + +# Test: c_variable-4.61 +# Desc: children of struct_declarations.s2.u2.u1s1 +gdbtk_test c_variable-4.61 {children of struct_declarations.s2.u2.u1s1} { + get_children struct_declarations.s2.u2.u1s1 +} {d e func foo} + +# Test: c_variable-4.62 +# Desc: number of children of struct_declarations.s2.u2.u1s1 +gdbtk_test c_variable-4.62 {number of children of struct_declarations.s2.u2.u1s1} { + $var(struct_declarations.s2.u2.u1s1) numChildren +} {4} + +# Test: c_variable-4.63 +# Desc: children of struct_declarations.s2.u2.f +gdbtk_test c_variable-4.63 {children of struct_declarations.s2.u2.f} { + get_children struct_declarations.s2.u2.f +} {} + +# Test: c_variable-4.64 +# Desc: number of children of struct_declarations.s2.u2.f +gdbtk_test c_variable-4.64 {number of children of struct_declarations.s2.u2.f} { + $var(struct_declarations.s2.u2.f) numChildren +} {0} + +# Test: c_variable-4.65 +# Desc: children of struct_declarations.s2.u2.u1s2 +gdbtk_test c_variable-4.65 {children of struct_declarations.s2.u2.u1s2} { + get_children struct_declarations.s2.u2.u1s2 +} {array_ptr func} + +# Test: c_variable-4.66 +# Desc: number of children of struct_declarations.s2.u2.u1s2 +gdbtk_test c_variable-4.66 {number of children of struct_declarations.s2.u2.u1s2} { + $var(struct_declarations.s2.u2.u1s2) numChildren +} {2} + +# Test: c_variable-4.67 +# Desc: children of struct_declarations.s2.u2.u1s1.d +gdbtk_test c_variable-4.67 {children of struct_declarations.s2.u2.u1s1.d} { + get_children struct_declarations.s2.u2.u1s1.d +} {} + +# Test: c_variable-4.68 +# Desc: number of children of struct_declarations.s2.u2.u1s1.d +gdbtk_test c_variable-4.68 {number of children of struct_declarations.s2.u2.u1s1.d} { + $var(struct_declarations.s2.u2.u1s1.d) numChildren +} {0} + +# Test: c_variable-4.69 +# Desc: children of struct_declarations.s2.u2.u1s1.e +gdbtk_test c_variable-4.69 {children of struct_declarations.s2.u2.u1s1.e} { + get_children struct_declarations.s2.u2.u1s1.e +} {0 1 2 3 4 5 6 7 8 9} + +# Test: c_variable-4.70 +# Desc: number of children of struct_declarations.s2.u2.u1s1.e +gdbtk_test c_variable-4.70 {number of children of struct_declarations.s2.u2.u1s1.e} { + $var(struct_declarations.s2.u2.u1s1.e) numChildren +} {10} + +# Test: c_variable-4.71 +# Desc: children of struct_declarations.s2.u2.u1s1.func +gdbtk_test c_variable-4.71 {children of struct_declarations.s2.u2.u1s1.func} { + get_children struct_declarations.s2.u2.u1s1.func +} {} + +# Test: c_variable-4.72 +# Desc: number of children of struct_declarations.s2.u2.u1s1.func +gdbtk_test c_variable-4.72 {number of children of struct_declarations.s2.u2.u1s1.func} { + $var(struct_declarations.s2.u2.u1s1.func) numChildren +} {0} + +# Test: c_variable-4.73 +# Desc: children of struct_declarations.s2.u2.u1s1.foo +gdbtk_test c_variable-4.73 {children of struct_declarations.s2.u2.u1s1.foo} { + get_children struct_declarations.s2.u2.u1s1.foo +} {} + +# Test: c_variable-4.74 +# Desc: number of children of struct_declarations.s2.u2.u1s1.foo +gdbtk_test c_variable-4.74 {number of children of struct_declarations.s2.u2.u1s1.foo} { + $var(struct_declarations.s2.u2.u1s1.foo) numChildren +} {0} + +# Test: c_variable-4.75 +# Desc: children of struct_declarations.s2.u2.u1s2.array_ptr +gdbtk_test c_variable-4.75 {children of struct_declarations.s2.u2.u1s2.array_ptr} { + get_children struct_declarations.s2.u2.u1s2.array_ptr +} {0 1} + +# Test: c_variable-4.76 +# Desc: number of children of struct_declarations.s2.u2.u1s2.array_ptr +gdbtk_test c_variable-4.76 {number of children of struct_declarations.s2.u2.u1s2.array_ptr} { + $var(struct_declarations.s2.u2.u1s2.array_ptr) numChildren +} {2} + +# Test: c_variable-4.77 +# Desc: children of struct_declarations.s2.u2.u1s2.func +gdbtk_test c_variable-4.77 {children of struct_declarations.s2.u2.u1s2.func} { + get_children struct_declarations.s2.u2.u1s2.func +} {} + +# Test: c_variable-4.78 +# Desc: number of children of struct_declarations.s2.u2.u1s2.func +gdbtk_test c_variable-4.78 {number of children of struct_declarations.s2.u2.u1s2.func} { + $var(struct_declarations.s2.u2.u1s2.func) numChildren +} {0} + +# Test: c_variable-4.79 +# Desc: children of struct_declarations.*int_ptr_ptr +gdbtk_test c_variable-4.79 {children of struct_declarations.*int_ptr_ptr} { + get_children struct_declarations.int_ptr_ptr.*int_ptr_ptr +} {**int_ptr_ptr} + +# Test: c_variable-4.80 +# Desc: Number of children of struct_declarations.*int_ptr_ptr +gdbtk_test c_variable-4.80 {Number of children of struct_declarations.*int_ptr_ptr} { + $var(struct_declarations.int_ptr_ptr.*int_ptr_ptr) numChildren +} {1} + +# Step to "struct_declarations.integer = 123;" +gdb_cmd "step" + +# Test: c_variable-4.81 +# Desc: create local variable "weird" +gdbtk_test c_variable-4.81 {create local variable "weird"} { + create_variable weird +} {0} + +# Test: c_variable-4.82 +# Desc: children of weird +gdbtk_test c_variable-4.82 {children of weird} { + get_children weird +} {integer character char_ptr long_int int_ptr_ptr long_array func_ptr func_ptr_struct func_ptr_ptr u1 s2} + +# Test: c_variable-4.83 +# Desc: number of children of weird +gdbtk_test c_variable-4.83 {number of children of weird} { + $var(weird) numChildren +} {11} + +# Test: c_variable-4.84 +# Desc: children of weird->long_array +gdbtk_test c_variable-4.84 {children of weird->long_array} { + get_children weird.long_array +} {0 1 2 3 4 5 6 7 8 9} + +# Test: c_variable-4.85 +# Desc: number of children of weird->long_array +gdbtk_test c_variable-4.85 {number of children of weird->long_array} { + $var(weird.long_array) numChildren +} {10} + +# Test: c_variable-4.86 +# Desc: children of weird->int_ptr_ptr +gdbtk_test c_variable-4.86 {children of weird->int_ptr_ptr} { + get_children weird.int_ptr_ptr +} {*int_ptr_ptr} + +# Test: c_variable-4.87 +# Desc: number of children of weird->int_ptr_ptr +gdbtk_test c_variable-4.87 {number of children of weird->int_ptr_ptr} { + $var(weird.int_ptr_ptr) numChildren +} {1} + +# Test: c_variable-4.88 +# Desc: children of *weird->int_ptr_ptr +gdbtk_test c_variable-4.88 {children of *weird->int_ptr_ptr} { + get_children weird.int_ptr_ptr.*int_ptr_ptr +} {**int_ptr_ptr} + +# Test: c_variable-4.89 +# Desc: number of children *weird->int_ptr_ptr +gdbtk_test c_variable-4.89 {number of children *weird->int_ptr_ptr} { + $var(weird.int_ptr_ptr.*int_ptr_ptr) numChildren +} {1} + +# Test: c_variable-4.90 +# Desc: create weird->int_ptr_ptr +gdbtk_test c_variable-4.90 {create weird->int_ptr_ptr} { + create_variable weird->int_ptr_ptr +} {0} + +# Test: c_variable-4.91 +# Desc: children of weird->int_ptr_ptr +gdbtk_test c_variable-4.91 {children of weird->int_ptr_ptr} { + get_children weird->int_ptr_ptr +} {*weird->int_ptr_ptr} + +# Test: c_variable-4.92 +# Desc: number of children of (weird->int_ptr_ptr) +gdbtk_test c_variable-4.92 {number of children of (weird->int_ptr_ptr)} { + $var(weird->int_ptr_ptr) numChildren +} {1} + +# Test: c_variable-4.93 +# Desc: children of *(weird->int_ptr_ptr) +gdbtk_test c_variable-4.93 {children of *(weird->int_ptr_ptr)} { + get_children weird->int_ptr_ptr.*weird->int_ptr_ptr +} {**weird->int_ptr_ptr} + +# Test: c_variable-4.94 +# Desc: number of children of *(weird->int_ptr_ptr) +gdbtk_test c_variable-4.94 {number of children of *(weird->int_ptr_ptr)} { + $var(weird->int_ptr_ptr.*weird->int_ptr_ptr) numChildren +} {1} + +# Test: c_variable-4.95 +# Desc: children of *(*(weird->int_ptr_ptr)) +gdbtk_test c_variable-4.95 {children of *(*(weird->int_ptr_ptr))} { + get_children weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr +} {} + +# Test: c_variable-4.96 +# Desc: number of children of *(*(weird->int_ptr_ptr)) +gdbtk_test c_variable-4.96 {number of children of **weird->int_ptr_ptr} { + $var(weird->int_ptr_ptr.*weird->int_ptr_ptr.**weird->int_ptr_ptr) numChildren +} {0} + +# Test: c_variable-4.97 +# Desc: is weird editable +gdbtk_test c_variable-4.97 {is weird editable} { + $var(weird) editable +} {1} + +# Test: c_variable-4.98 +# Desc: is weird->int_ptr_ptr editable +gdbtk_test c_variable-4.98 {is weird->int_ptr_ptr editable} { + $var(weird.int_ptr_ptr) editable +} {1} + +# Test: c_variable-4.99 +# Desc: is *(weird->int_ptr_ptr) editable +gdbtk_test c_variable-4.99 {is *(weird->int_ptr_ptr) editable} { + $var(weird.int_ptr_ptr.*int_ptr_ptr) editable +} {1} + +# Test: c_variable-4.100 +# Desc: is *(*(weird->int_ptr_ptr)) editable +gdbtk_test c_variable-4.100 {is *(*(weird->int_ptr_ptr)) editable} { + $var(weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr) editable +} {1} + +# Test: c_variable-4.101 +# Desc: is weird->u1 editable +gdbtk_test c_variable-4.101 {is weird->u1 editable} { + $var(weird.u1) editable +} {0} + +# Test: c_variable-4.102 +# Desc: is weird->s2 editable +gdbtk_test c_variable-4.102 {is weird->s2 editable} { + $var(weird.s2) editable +} {0} + +# Test: c_variable-4.103 +# Desc: is struct_declarations.u1.a editable +gdbtk_test c_variable-4.103 {is struct_declarations.u1.a editable} { + $var(struct_declarations.u1.a) editable +} {1} + +# Test: c_variable-4.104 +# Desc: is struct_declarations.u1.b editable +gdbtk_test c_variable-4.104 {is struct_declarations.u1.b editable} { + $var(struct_declarations.u1.b) editable +} {1} + +# Test: c_variable-4.105 +# Desc: is struct_declarations.u1.c editable +gdbtk_test c_variable-4.105 {is struct_declarations.u1.c editable} { + $var(struct_declarations.u1.c) editable +} {1} + +# Test: c_variable-4.106 +# Desc: is struct_declarations.long_array editable +gdbtk_test c_variable-4.106 {is struct_declarations.long_array editable} { + $var(struct_declarations.long_array) editable +} {0} + +# Test: c_variable-4.107 +# Desc: is struct_declarations.long_array[0] editable +gdbtk_test c_variable-4.107 {is struct_declarations.long_array[0] editable} { + $var(struct_declarations.long_array.0) editable +} {1} + +# Test: c_variable-4.108 +# Desc: is struct_declarations editable +gdbtk_test c_variable-4.108 {is struct_declarations editable} { + $var(struct_declarations) editable +} {0} + +delete_variable weird + +##### ##### +# # +# children and update tests # +# # +##### ##### + +# Test: c_variable-5.1 +# Desc: check that nothing changed +gdbtk_test c_variable-5.1 {check that nothing changed} { + check_update +} {{} {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over "struct_declarations.integer = 123;" +gdb_cmd "step" + +# Test: c_variable-5.2 +# Desc: check that integer changed +gdbtk_test c_variable-5.2 {check that integer changed} { + check_update +} {struct_declarations.integer {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over: +# weird->char_ptr = "hello"; +# bar = 2121; +# foo = &bar; +for {set i 0} {$i < 3} {incr i} { + gdb_cmd "step" +} + +# Test: c_variable-5.3 +# Desc: check that char_ptr changed +gdbtk_test c_variable-5.3 {check that char_ptr changed} { + check_update +} {struct_declarations.char_ptr {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over "struct_declarations.int_ptr_ptr = &foo;" +gdb_cmd "step" + +# Test: c_variable-5.4 +# Desc: check that int_ptr_ptr and children changed +gdbtk_test c_variable-5.4 {check that int_ptr_ptr and children changed} { + check_update +} {{struct_declarations.int_ptr_ptr struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr} {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over "weird->long_array[0] = 1234;" +gdb_cmd "step" + +# Test: c_variable-5.5 +# Desc: check that long_array[0] changed +gdbtk_test c_variable-5.5 {check that long_array[0] changed} { + check_update +} {struct_declarations.long_array.0 {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over "struct_declarations.long_array[1] = 2345;" +gdb_cmd "step" + +# Test: c_variable-5.6 +# Desc: check that long_array[1] changed +gdbtk_test c_variable-5.6 {check that long_array[1] changed} { + check_update +} {struct_declarations.long_array.1 {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over "weird->long_array[2] = 3456;" +gdb_cmd "step" + +# Test: c_variable-5.7 +# Desc: check that long_array[2] changed +gdbtk_test c_variable-5.7 {check that long_array[2] changed} { + check_update +} {struct_declarations.long_array.2 {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over: +# struct_declarations.long_array[3] = 4567; +# weird->long_array[4] = 5678; +# struct_declarations.long_array[5] = 6789; +# weird->long_array[6] = 7890; +# struct_declarations.long_array[7] = 8901; +# weird->long_array[8] = 9012; +# struct_declarations.long_array[9] = 1234; +for {set i 0} {$i < 7} {incr i} { + gdb_cmd "step" +} + +# Test: c_variable-5.8 +# Desc: check that long_array[3-9] changed +gdbtk_test c_variable-5.8 {check that long_array[3-9] changed} { + check_update +} {{struct_declarations.long_array.3 struct_declarations.long_array.4 struct_declarations.long_array.5 struct_declarations.long_array.6 struct_declarations.long_array.7 struct_declarations.long_array.8 struct_declarations.long_array.9} {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.func_ptr struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.character struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Step over "weird->func_ptr = nothing;" +gdb_cmd "step" + +# Test: c_variable-5.9 +# Desc: check that func_ptr changed +gdbtk_test c_variable-5.9 {check that func_ptr changed} { + check_update +} {struct_declarations.func_ptr {struct_declarations.s2.i.3 struct_declarations.func_ptr_ptr struct_declarations.s2.i.4 struct_declarations.s2.i.5 struct_declarations.s2.i.6 struct_declarations.s2.i.7 struct_declarations.s2.i.8 struct_declarations.s2.i.9 struct_declarations.s2.u2.u1s1.d struct_declarations.func_ptr_struct struct_declarations.s2.u2.u1s1.e struct_declarations.u1 struct_declarations.long_int struct_declarations.s2.u2.u1s2.func struct_declarations.integer struct_declarations.s2.u2 struct_declarations.s2.u2.u1s1.e.0 struct_declarations.s2.u2.u1s1.e.1 struct_declarations.long_array.0 struct_declarations.s2.u2.u1s1.e.2 struct_declarations.long_array.1 struct_declarations.u1.a struct_declarations.s2.u2.u1s1.e.3 struct_declarations.long_array.2 struct_declarations.u1.b struct_declarations.s2.u2.u1s1.e.4 struct_declarations.long_array.3 struct_declarations.u1.c struct_declarations.s2.u2.u1s1.e.5 struct_declarations.long_array.4 struct_declarations.u1.d struct_declarations.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr struct_declarations.s2.u2.u1s1.e.6 struct_declarations.long_array.5 struct_declarations.s2.u2.u1s1.e.7 struct_declarations.long_array.6 struct_declarations.s2.u2.u1s1.e.8 struct_declarations.long_array.7 struct_declarations.s2.u2.u1s1.e.9 struct_declarations.long_array.8 struct_declarations.character struct_declarations.long_array.9 struct_declarations.int_ptr_ptr.*int_ptr_ptr struct_declarations.s2.u2.u1s1.func struct_declarations.s2.u2.u1s2.array_ptr struct_declarations.s2.u2.f struct_declarations.s2.u2.u1s1.foo struct_declarations struct_declarations.s2.u2.u1s1 struct_declarations.s2.u2.u1s2.array_ptr.0 struct_declarations.char_ptr struct_declarations.s2.u2.u1s2 struct_declarations.s2.u2.u1s2.array_ptr.1 struct_declarations.int_ptr_ptr struct_declarations.s2 struct_declarations.long_array struct_declarations.s2.g struct_declarations.s2.i.0 struct_declarations.s2.h struct_declarations.s2.i.1 struct_declarations.s2.i struct_declarations.s2.i.2} {}} + +# Delete all variables +delete_all_variables + +# Step over all lines: +# ... +# psnp = &snp0; +for {set i 0} {$i < 43} {incr i} { + gdb_cmd "step" +} + +# Test: c_variable-5.10 +# Desc: create psnp->char_ptr +gdbtk_test c_variable-5.10 {create psnp->char_ptr} { + create_variable psnp->char_ptr +} {0} + +# Test: c_variable-5.11 +# Desc: children of psnp->char_ptr +gdbtk_test c_variable-5.11 {children of psnp->char_ptr} { + get_children psnp->char_ptr +} {*psnp->char_ptr} + +# Test: c_variable-5.12 +# Desc: number of children of psnp->char_ptr +gdbtk_test c_variable-5.12 {number of children of psnp->char_ptr} { + $var(psnp->char_ptr) numChildren +} {1} + +# Test: c_variable-5.13 +# Desc: children of *(psnp->char_ptr) +gdbtk_test c_variable-5.13 {children of *(psnp->char_ptr)} { + get_children psnp->char_ptr.*psnp->char_ptr +} {**psnp->char_ptr} + +# Test: c_variable-5.14 +# Desc: number of children of *(psnp->char_ptr) +gdbtk_test c_variable-5.14 {number of children of *(psnp->char_ptr)} { + $var(psnp->char_ptr.*psnp->char_ptr) numChildren +} {1} + +# Test: c_variable-5.15 +# Desc: children of *(*(psnp->char_ptr)) +gdbtk_test c_variable-5.15 {children of *(*(psnp->char_ptr))} { + get_children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr +} {***psnp->char_ptr} + +# Test: c_variable-5.16 +# Desc: number of children of *(*(psnp->char_ptr)) +gdbtk_test c_variable-5.16 {number of children of *(*(psnp->char_ptr))} { + $var(psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr) numChildren +} {1} + +# Test: c_variable-5.17 +# Desc: children of *(*(*(psnp->char_ptr))) +gdbtk_test c_variable-5.17 {children of *(*(*(psnp->char_ptr)))} { + get_children psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr +} {} + +# Test: c_variable-5.18 +# Desc: number of children of *(*(*(psnp->char_ptr))) +gdbtk_test c_variable-5.18 {number of children of *(*(*(psnp->char_ptr)))} { + $var(psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr) numChildren +} {0} + +# Test: c_variable-5.19 +# Desc: create psnp->long_ptr +gdbtk_test c_variable-5.19 {create psnp->long_ptr} { + create_variable psnp->long_ptr +} {0} + +# Test: c_variable-5.20 +# Desc: children of psnp->long_ptr +gdbtk_test c_variable-5.20 {children of psnp->long_ptr} { + get_children psnp->long_ptr +} {*psnp->long_ptr} + +# Test: c_variable-5.21 +# Desc: number of children of psnp->long_ptr +gdbtk_test c_variable-5.21 {number of children of psnp->long_ptr} { + $var(psnp->long_ptr) numChildren +} {1} + +# Test: c_variable-5.22 +# Desc: children of *(psnp->long_ptr) +gdbtk_test c_variable-5.22 {children of *(psnp->long_ptr)} { + get_children psnp->long_ptr.*psnp->long_ptr +} {**psnp->long_ptr} + +# Test: c_variable-5.23 +# Desc: number of children of *(psnp->long_ptr) +gdbtk_test c_variable-5.23 {number of children of *(psnp->long_ptr)} { + $var(psnp->long_ptr.*psnp->long_ptr) numChildren +} {1} + +# Test: c_variable-5.24 +# Desc: children of *(*(psnp->long_ptr)) +gdbtk_test c_variable-5.24 {children of *(*(psnp->long_ptr))} { + get_children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr +} {***psnp->long_ptr} + +# Test: c_variable-5.25 +# Desc: number of children of *(*(psnp->long_ptr)) +gdbtk_test c_variable-5.25 {number of children of *(*(psnp->long_ptr))} { + $var(psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr) numChildren +} {1} + +# Test: c_variable-5.26 +# Desc: children of *(*(*(psnp->long_ptr))) +gdbtk_test c_variable-5.26 {children of *(*(*(psnp->long_ptr)))} { + get_children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr +} {****psnp->long_ptr} + +# Test: c_variable-5.27 +# Desc: number of children of *(*(*(psnp->long_ptr))) +gdbtk_test c_variable-5.27 {number of children of *(*(*(psnp->long_ptr)))} { + $var(psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr) numChildren +} {1} + +# Test: c_variable-5.28 +# Desc: children of *(*(*(*(psnp->long_ptr)))) +gdbtk_test c_variable-5.29 {children of *(*(*(*(psnp->long_ptr))))} { + get_children psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr +} {} + +# Test: c_variable-5.29 +# Desc: number of children of *(*(*(*(psnp->long_ptr)))) +gdbtk_test c_variable-5.29 {number of children of *(*(*(*(psnp->long_ptr))))} { + $var(psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr) numChildren +} {0} + +# Test: c_variable-5.30 +# Desc: create psnp->ptrs +gdbtk_test c_variable-5.30 {create psnp->ptrs} { + create_variable psnp->ptrs +} {0} + +# Test: c_variable-5.31 +# Desc: children of psnp->ptrs +gdbtk_test c_variable-5.31 {children of psnp->ptrs} { + get_children psnp->ptrs +} {0 1 2} + +# Test: c_variable-5.32 +# Desc: number of children of psnp->ptrs +gdbtk_test c_variable-5.32 {number of children of psnp->ptrs} { + $var(psnp->ptrs) numChildren +} {3} + +# Test: c_variable-5.33 +# Desc: children of psnp->ptrs[0] +gdbtk_test c_variable-5.33 {children of psnp->ptrs[0]} { + get_children psnp->ptrs.0 +} {char_ptr long_ptr ptrs next} + +# Test: c_variable-5.34 +# Desc: number of children of psnp->ptrs[0] +gdbtk_test c_variable-5.34 {number of children of psnp->ptrs[0]} { + $var(psnp->ptrs.0) numChildren +} {4} + +# Test: c_variable-5.35 +# Desc: children of psnp->ptrs[0]->next +gdbtk_test c_variable-5.35 {children of psnp->ptrs.0.next} { + get_children psnp->ptrs.0.next +} {char_ptr long_ptr ptrs next} + +# Test: c_variable-5.36 +# Desc: number of children of psnp->ptrs[0]->next +gdbtk_test c_variable-5.36 {number of children of psnp->ptrs[0]->next} { + $var(psnp->ptrs.0.next) numChildren +} {4} + +# Test: c_variable-5.37 +# Desc: children of psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.37 {children of psnp->ptrs[0]->next->char_ptr} { + get_children psnp->ptrs.0.next.char_ptr +} {*char_ptr} + +# Test: c_variable-5.38 +# Desc: number of children of psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.38 {number of children of psnp->ptrs[0]->next->char_ptr} { + $var(psnp->ptrs.0.next.char_ptr) numChildren +} {1} + +# Test: c_variable-5.39 +# Desc: children of *psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.39 {children of *psnp->ptrs[0]->next->char_ptr} { + get_children psnp->ptrs.0.next.char_ptr.*char_ptr +} {**char_ptr} + +# Test: c_variable-5.40 +# Desc: number of children of *psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.40 {number of children of *psnp->ptrs[0]->next->char_ptr} { + $var(psnp->ptrs.0.next.char_ptr.*char_ptr) numChildren +} {1} + +# Test: c_variable-5.41 +# Desc: children of **psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.41 {children of **psnp->ptrs[0]->next->char_ptr} { + get_children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr +} {***char_ptr} + +# Test: c_variable-5.42 +# Desc: number of children of **psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.42 {number of children of **psnp->ptrs[0]->next->char_ptr} { + $var(psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr) numChildren +} {1} + +# Test: c_variable-5.43 +# Desc: children of ***psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.43 {children of ***psnp->ptrs[0]->next->char_ptr} { + get_children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr +} {} + +# Test: c_variable-5.44 +# Desc: number of children of ***psnp->ptrs[0]->next->char_ptr +gdbtk_test c_variable-5.44 {number of children of ***psnp->ptrs[0]->next->char_ptr} { + $var(psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr) numChildren +} {0} + +# Test: c_variable-5.45 +# Desc: children of psnp->ptrs[0]->next->next +gdbtk_test c_variable-5.45 {children of psnp->ptrs[0]->next->next} { + get_children psnp->ptrs.0.next.next +} {char_ptr long_ptr ptrs next} + +# Test: c_variable-5.46 +# Desc: children of psnp->ptrs[0]->next->next->ptrs +gdbtk_test c_variable-5.46 {children of psnp->ptrs[0]->next->next->ptrs} { + get_children psnp->ptrs.0.next.next.ptrs +} {0 1 2} + +# Step over "snp0.char_ptr = &b3;" +gdb_cmd "step" + +# Test: c_variable-5.47 +# Desc: check that psnp->char_ptr (and [0].char_ptr) changed +gdbtk_test c_variable-5.47 {check that psnp->char_ptr (and [0].char_ptr) changed} { + check_update +} {{psnp->ptrs.0.char_ptr psnp->char_ptr psnp->char_ptr.*psnp->char_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr} {psnp->ptrs.0.next psnp->ptrs.0.next.ptrs psnp->ptrs.0.next.next psnp->ptrs.0.next.next.char_ptr psnp->ptrs.0.next.next.long_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr psnp->ptrs.0.next.char_ptr psnp->ptrs.0.next.long_ptr psnp->ptrs.0.next.next.ptrs psnp->ptrs.0.next.char_ptr.*char_ptr psnp->ptrs psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr psnp->ptrs.0.next.next.next psnp->ptrs.0.next.next.ptrs.0 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr psnp->long_ptr.*psnp->long_ptr psnp->ptrs.0.next.next.ptrs.1 psnp->ptrs.0.next.next.ptrs.2 psnp->ptrs.0.long_ptr psnp->long_ptr psnp->ptrs.0.ptrs psnp->ptrs.0 psnp->ptrs.1 psnp->ptrs.2 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr} {}} + +# Step over "snp1.char_ptr = &c3;" +gdb_cmd "step" + +# Test: c_variable-5.48 +# Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed +gdbtk_test c_variable-5.48 {check that psnp->next->char_ptr (and [1].char_ptr) changed} { + check_update +} {{psnp->ptrs.0.next.char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr} {psnp->ptrs.0.next psnp->ptrs.0.next.ptrs psnp->ptrs.0.next.next psnp->ptrs.0.next.next.char_ptr psnp->ptrs.0.next.next.long_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr psnp->ptrs.0.next.long_ptr psnp->ptrs.0.next.next.ptrs psnp->ptrs psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr psnp->ptrs.0.next.next.next psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr psnp->char_ptr.*psnp->char_ptr psnp->ptrs.0.next.next.ptrs.0 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr psnp->long_ptr.*psnp->long_ptr psnp->ptrs.0.next.next.ptrs.1 psnp->ptrs.0.next.next.ptrs.2 psnp->ptrs.0.char_ptr psnp->ptrs.0.long_ptr psnp->char_ptr psnp->long_ptr psnp->ptrs.0.ptrs psnp->ptrs.0 psnp->ptrs.1 psnp->ptrs.2 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr} {}} + +# Step over "snp2.char_ptr = &a3;" +gdb_cmd "step" + +# Test: c_variable-5.49 +# Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed +gdbtk_test c_variable-5.49 {heck that psnp->next->next->char_ptr (and [2].char_ptr) changed} { + check_update +} {psnp->ptrs.0.next.next.char_ptr {psnp->ptrs.0.next psnp->ptrs.0.next.ptrs psnp->ptrs.0.next.next psnp->ptrs.0.next.next.long_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr psnp->ptrs.0.next.char_ptr psnp->ptrs.0.next.long_ptr psnp->ptrs.0.next.next.ptrs psnp->ptrs.0.next.char_ptr.*char_ptr psnp->ptrs psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr psnp->ptrs.0.next.next.next psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr psnp->char_ptr.*psnp->char_ptr psnp->ptrs.0.next.next.ptrs.0 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr psnp->long_ptr.*psnp->long_ptr psnp->ptrs.0.next.next.ptrs.1 psnp->ptrs.0.next.next.ptrs.2 psnp->ptrs.0.char_ptr psnp->ptrs.0.long_ptr psnp->char_ptr psnp->long_ptr psnp->ptrs.0.ptrs psnp->ptrs.0 psnp->ptrs.1 psnp->ptrs.2 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr} {}} + +# Step over "snp0.long_ptr = &y3;" +gdb_cmd "step" + +# Test: c_variable-5.50 +# Desc: check that psnp->long_ptr (and [0].long_ptr) changed +gdbtk_test c_variable-5.50 {check that psnp->long_ptr (and [0].long_ptr) changed} { + check_update +} {{psnp->ptrs.0.long_ptr psnp->long_ptr psnp->long_ptr.*psnp->long_ptr psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr} {psnp->ptrs.0.next psnp->ptrs.0.next.ptrs psnp->ptrs.0.next.next psnp->ptrs.0.next.next.char_ptr psnp->ptrs.0.next.next.long_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr psnp->ptrs.0.next.char_ptr psnp->ptrs.0.next.long_ptr psnp->ptrs.0.next.next.ptrs psnp->ptrs.0.next.char_ptr.*char_ptr psnp->ptrs psnp->ptrs.0.next.next.next psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr psnp->char_ptr.*psnp->char_ptr psnp->ptrs.0.next.next.ptrs.0 psnp->ptrs.0.next.next.ptrs.1 psnp->ptrs.0.next.next.ptrs.2 psnp->ptrs.0.char_ptr psnp->char_ptr psnp->ptrs.0.ptrs psnp->ptrs.0 psnp->ptrs.1 psnp->ptrs.2} {}} + +# Step over "snp1.long_ptr = &x3;" +gdb_cmd "step" + +# Test: c_variable-5.51 +# Desc: check that psnp->next->long_ptr (and [1].long_ptr) changed +gdbtk_test c_variable-5.51 {check that psnp->next->long_ptr (and [1].long_ptr) changed} { + check_update +} {psnp->ptrs.0.next.long_ptr {psnp->ptrs.0.next psnp->ptrs.0.next.ptrs psnp->ptrs.0.next.next psnp->ptrs.0.next.next.char_ptr psnp->ptrs.0.next.next.long_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr psnp->ptrs.0.next.char_ptr psnp->ptrs.0.next.next.ptrs psnp->ptrs.0.next.char_ptr.*char_ptr psnp->ptrs psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr psnp->ptrs.0.next.next.next psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr psnp->char_ptr.*psnp->char_ptr psnp->ptrs.0.next.next.ptrs.0 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr psnp->long_ptr.*psnp->long_ptr psnp->ptrs.0.next.next.ptrs.1 psnp->ptrs.0.next.next.ptrs.2 psnp->ptrs.0.char_ptr psnp->ptrs.0.long_ptr psnp->char_ptr psnp->long_ptr psnp->ptrs.0.ptrs psnp->ptrs.0 psnp->ptrs.1 psnp->ptrs.2 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr} {}} + +# Step over "snp2.long_ptr = &z3;" +gdb_cmd "step" + +# Test: c_variable-5.52 +# Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed +gdbtk_test c_variable-5.52 {check that psnp->next->next->long_ptr (and [2].long_ptr) changed} { + check_update +} {psnp->ptrs.0.next.next.long_ptr {psnp->ptrs.0.next psnp->ptrs.0.next.ptrs psnp->ptrs.0.next.next psnp->ptrs.0.next.next.char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr psnp->ptrs.0.next.char_ptr psnp->ptrs.0.next.long_ptr psnp->ptrs.0.next.next.ptrs psnp->ptrs.0.next.char_ptr.*char_ptr psnp->ptrs psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr psnp->ptrs.0.next.next.next psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr psnp->char_ptr.*psnp->char_ptr psnp->ptrs.0.next.next.ptrs.0 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr psnp->long_ptr.*psnp->long_ptr psnp->ptrs.0.next.next.ptrs.1 psnp->ptrs.0.next.next.ptrs.2 psnp->ptrs.0.char_ptr psnp->ptrs.0.long_ptr psnp->char_ptr psnp->long_ptr psnp->ptrs.0.ptrs psnp->ptrs.0 psnp->ptrs.1 psnp->ptrs.2 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr} {}} + +# Test: c_variable-5.53 +# Desc: names of editable variables +gdbtk_test c_variable-5.53 {names of editable variables} { + editable_variables +} {{psnp->ptrs.0.next psnp->ptrs.0.next.next psnp->ptrs.0.next.next.char_ptr psnp->ptrs.0.next.next.long_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr.***char_ptr psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr psnp->ptrs.0.next.char_ptr.*char_ptr.**char_ptr psnp->ptrs.0.next.char_ptr psnp->ptrs.0.next.long_ptr psnp->ptrs.0.next.char_ptr.*char_ptr psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr.****psnp->long_ptr psnp->ptrs.0.next.next.next psnp->char_ptr.*psnp->char_ptr.**psnp->char_ptr.***psnp->char_ptr psnp->char_ptr.*psnp->char_ptr psnp->ptrs.0.next.next.ptrs.0 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr psnp->long_ptr.*psnp->long_ptr psnp->ptrs.0.next.next.ptrs.1 psnp->ptrs.0.next.next.ptrs.2 psnp->ptrs.0.char_ptr psnp->ptrs.0.long_ptr psnp->char_ptr psnp->long_ptr psnp->ptrs.0 psnp->ptrs.1 psnp->ptrs.2 psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr} {psnp->ptrs.0.next.ptrs psnp->ptrs.0.next.next.ptrs psnp->ptrs psnp->ptrs.0.ptrs}} + +##### ##### +# # +# Display tests # +# # +##### ##### + +delete_all_variables + +# Test: c_variable-6.1 +# Desc: create variable bar +gdbtk_test c_variable-6.1 {create variable bar} { + create_variable bar +} {0} + +# Test: c_variable-6.2 +# Desc: type of variable bar +gdbtk_test c_variable-6.2 {type of variable bar} { + $var(bar) type +} {int} + +# Test: c_variable-6.3 +# Desc: format of variable bar +gdbtk_test c_variable-6.3 {format of variable bar} { + $var(bar) format +} {natural} + +# Test: c_variable-6.4 +# Desc: value of variable bar +gdbtk_test c_variable-6.4 {value of variable bar} { + value bar d +} {ok} + +# Test: c_variable-6.5 +# Desc: change format of bar to hex +gdbtk_test c_variable-6.5 {change format of bar to hex} { + $var(bar) format hex + $var(bar) format +} {hexadecimal} + +# Test: c_variable-6.6 +# Desc: value of bar with new format +gdbtk_test c_variable-6.6 {value of bar with new format} { + value bar x +} {ok} + +# Test: c_variable-6.7 +# Desc: change value of bar +gdbtk_test c_variable-6.7 {change value of bar} { + $var(bar) value 3 + value bar x +} {ok} + +# Test: c_variable-6.8 +# Desc: check new value of bar +gdbtk_test c_variable-6.8 {change value of bar} { + $var(bar) format decimal + $var(bar) value +} {3} + +delete_variable bar + +# Test: c_variable-6.11 +# Desc: create variable foo +gdbtk_test c_variable-6.11 {create variable foo} { + create_variable foo +} {0} + +# Test: c_variable-6.12 +# Desc: type of variable foo +gdbtk_test c_variable-6.12 {type of variable foo} { + $var(foo) type +} {int *} + +# Test: c_variable-6.13 +# Desc: format of variable foo +gdbtk_test c_variable-6.13 {format of variable foo} { + $var(foo) format +} {natural} + +# Test: c_variable-6.14 +# Desc: value of variable foo +gdbtk_test c_variable-6.14 {value of variable foo} { + value foo x +} {ok} + +# Test: c_variable-6.15 +# Desc: change format of var to octal +gdbtk_test c_variable-6.15 {change format of foo to octal} { + $var(foo) format octal + $var(foo) format +} {octal} + +# Test: c_variable-6.16 +# Desc: value of foo with new format +gdbtk_test c_variable-6.16 {value of foo with new format} { + value foo o +} {ok} + +# Test: c_variable-6.17 +# Desc: change value of foo +gdbtk_test c_variable-6.17 {change value of foo} { + $var(foo) value 3 + value foo o +} {ok} + +# Test: c_variable-6.18 +# Desc: check new value of foo +gdbtk_test c_variable-6.18 {check new value of foo} { + $var(foo) format decimal + $var(foo) value +} {3} + +delete_variable foo + +# Test: c_variable-6.21 +# Desc: create variable weird and children +gdbtk_test c_variable-6.21 {create variable foo} { + if {![create_variable weird]} { + lsort [get_children weird] + } +} {char_ptr character func_ptr func_ptr_ptr func_ptr_struct int_ptr_ptr integer long_array long_int s2 u1} + +# Test: c_variable-6.22 +# Desc: type of weird and children +gdbtk_test c_variable-6.22 {type of weird and children} { + set types {} + foreach v [lsort [array names var]] { + lappend types [$var($v) type] + } + + set types +} {{weird_struct *} {char *} char {void (*)()} {struct _struct_decl *(*)()} {struct _struct_decl (*)()} {int **} int {long int [10]} {long int} struct union} + +# Test: c_variable-6.23 +# Desc: change format of weird.func_ptr and weird.func_ptr_ptr +gdbtk_test c_variable-6.23 {change format of weird.func_ptr and weird.func_ptr_ptr} { + $var(weird.func_ptr) format hexadecimal + $var(weird.func_ptr_ptr) format hexadecimal + set result {} + lappend result [$var(weird.func_ptr) format] + lappend result [$var(weird.func_ptr_ptr) format] + set result +} {hexadecimal hexadecimal} + +# Test: c_variable-6.24 +# Desc: format of weird and children +gdbtk_test c_variable-6.24 {format of weird and children} { + set formats {} + foreach v [lsort [array names var]] { + lappend formats [$var($v) format] + } + + set formats +} {natural natural natural hexadecimal hexadecimal natural natural natural natural natural natural natural} + +# Test: c_variable-6.25 +# Desc: value of weird and children +gdbtk_test c_variable-6.25 {value of weird and children} { + set values {} + foreach v [lsort [array names var]] f [list x "" "" x x x x d d d d d] { + lappend values [value $v $f] + } + + set values +} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1} + +# Test: c_variable-6.26 +# Desc: change format of weird and children to octal +gdbtk_test c_variable-6.26 {change format of weird and children to octal} { + set formats {} + foreach v [lsort [array names var]] { + $var($v) format octal + lappend formats [$var($v) format] + } + + set formats +} {octal octal octal octal octal octal octal octal octal octal octal octal} + +# Test: c_variable-6.27 +# Desc: value of weird and children with new format +gdbtk_test c_variable-6.27 {value of foo with new format} { + set values {} + foreach v [lsort [array names var]] { + lappend values [value $v o] + } + + set values +} {ok ok ok ok ok ok ok ok weird.long_array ok weird.s2 weird.u1} + +# Test: c_variable-6.30 +# Desc: create more children of weird +gdbtk_test c_variable-6.30 {create more children of weird} { + foreach v [array names var] { + get_children $v + } + + # Do it twice to get more children + foreach v [array names var] { + get_children $v + } + + lsort [array names var] +} {weird weird.char_ptr weird.character weird.func_ptr weird.func_ptr_ptr weird.func_ptr_struct weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.integer weird.long_array weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.long_int weird.s2 weird.s2.g weird.s2.h weird.s2.i weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9 weird.s2.u2 weird.s2.u2.f weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.u1 weird.u1.a weird.u1.b weird.u1.c weird.u1.d} + +# Test: c_variable-6.31 +# Desc: check that all children of weird change +# Ok, obviously things like weird.s2 and weird.u1 will not change! +gdbtk_test *c_variable-6.31 {check that all children of weird change (ops, we are now reporting array names as changed in this case - seems harmless though)} { + $var(weird) value 0x2121 + check_update +} {{weird.integer weird.character weird.char_ptr weird.long_int weird.int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr weird.int_ptr_ptr.*int_ptr_ptr.**int_ptr_ptr weird.long_array.0 weird.long_array.1 weird.long_array.2 weird.long_array.3 weird.long_array.4 weird.long_array.5 weird.long_array.6 weird.long_array.7 weird.long_array.8 weird.long_array.9 weird.func_ptr weird.func_ptr_struct weird.func_ptr_ptr weird.u1.a weird.u1.b weird.u1.c weird.u1.d weird.s2.u2.f weird.s2.g weird.s2.h weird.s2.i.0 weird.s2.i.1 weird.s2.i.2 weird.s2.i.3 weird.s2.i.4 weird.s2.i.5 weird.s2.i.6 weird.s2.i.7 weird.s2.i.8 weird.s2.i.9} {weird.s2.i weird.s2.u2 weird weird.s2.u2.u1s1 weird.s2.u2.u1s2 weird.s2 weird.long_array weird.u1} {}} + +delete_variable weird + +##### ##### +# # +# Special Display Tests # +# # +##### ##### + +# Stop in "do_special_tests" +gdb_cmd "break do_special_tests" +gdb_cmd "continue" + +# Test: c_variable-7.1 +# Desc: stop in do_special_tests +gdbtk_test c_variable-7.1 {stop in do_special_tests} { + lindex [gdb_loc] 1 +} {do_special_tests} + +# Test: c_variable-7.10 +# Desc: create union u +gdbtk_test c_variable-7.10 {create union u} { + create_variable u +} {0} + +# Test: c_variable-7.11 +# Desc: value of u +gdbtk_test c_variable-7.11 {value of u} { + $var(u) value +} {{...}} + +# Test: c_variable-7.12 +# Desc: type of u +gdbtk_test c_variable-7.12 {type of u} { + $var(u) type +} {union named_union} + +# Test: c_variable-7.13 +# Desc: is u editable +gdbtk_test c_variable-7.13 {is u editable} { + $var(u) editable +} {0} + +# Test: c_variable-7.14 +# Desc: number of children of u +gdbtk_test c_variable-7.14 {number of children of u} { + $var(u) numChildren +} {2} + +# Test: c_variable-7.15 +# Desc: children of u +gdbtk_test c_variable-7.15 {children of u} { + get_children u +} {integer char_ptr} + +# Test: c_variable-7.20 +# Desc: create anonu +gdbtk_test c_variable-7.20 {create anonu} { + create_variable anonu +} {0} + +# Test: c_variable-7.21 +# Desc: value of anonu +gdbtk_test c_variable-7.21 {value of anonu} { + $var(anonu) value +} {{...}} + +# Test: c_variable-7.22 +# Desc: type of anonu +gdbtk_test c_variable-7.22 {type of anonu} { + $var(anonu) type +} {union} + +# Test: c_variable-7.23 +# Desc: is anonu editable +gdbtk_test c_variable-7.23 {is anonu editable} { + $var(anonu) editable +} {0} + +# Test: c_variable-7.24 +# Desc: number of children of anonu +gdbtk_test c_variable-7.24 {number of children of anonu} { + $var(anonu) numChildren +} {3} + +# Test: c_variable-7.25 +# Desc: children of anonu +gdbtk_test c_variable-7.25 {children of anonu} { + get_children anonu +} {a b c} + +# Test: c_variable-7.30 +# Desc: create struct s +gdbtk_test c_variable-7.30 {create struct s} { + create_variable s +} {0} + +# Test: c_variable-7.31 +# Desc: value of s +gdbtk_test c_variable-7.31 {value of s} { + $var(s) value +} {{...}} + +# Test: c_variable-7.32 +# Desc: type of s +gdbtk_test c_variable-7.32 {type of s} { + $var(s) type +} {struct _simple_struct} + +# Test: c_variable-7.33 +# Desc: is s editable +gdbtk_test c_variable-7.33 {is s editable} { + $var(s) editable +} {0} + +# Test: c_variable-7.34 +# Desc: number of children of s +gdbtk_test c_variable-7.34 {number of children of s} { + $var(s) numChildren +} {6} + +# Test: c_variable-7.35 +# Desc: children of s +gdbtk_test c_variable-7.35 {children of s} { + get_children s +} {integer unsigned_integer character signed_character char_ptr array_of_10} + +# Test: c_variable-7.40 +# Desc: create anons +gdbtk_test c_variable-7.40 {create anons} { + create_variable anons +} {0} + +# Test: c_variable-7.41 +# Desc: value of anons +gdbtk_test c_variable-7.41 {value of anons} { + $var(anons) value +} {{...}} + +# Test: c_variable-7.42 +# Desc: type of anons +gdbtk_test c_variable-7.42 {type of anons} { + $var(anons) type +} {struct} + +# Test: c_variable-7.43 +# Desc: is anons editable +gdbtk_test c_variable-7.43 {is anons editable} { + $var(anons) editable +} {0} + +# Test: c_variable-7.44 +# Desc: number of children of anons +gdbtk_test c_variable-7.44 {number of children of anons} { + $var(anons) numChildren +} {3} + +# Test: c_variable-7.45 +# Desc: children of anons +gdbtk_test c_variable-7.45 {children of anons} { + get_children anons +} {a b c} + +# Test: c_variable-7.50 +# Desc: create enum e +gdbtk_test c_variable-7.50 {create enum e} { + create_variable e +} {0} + +# Test: c_variable-7.51 +# Desc: value of e +gdbtk_test c_variable-7.51 {value of e} { + $var(e) value bar + $var(e) value +} {bar} + +# Test: c_variable-7.52 +# Desc: type of e +gdbtk_test c_variable-7.52 {type of e} { + $var(e) type +} {enum foo} + +# Test: c_variable-7.53 +# Desc: is e editable +gdbtk_test c_variable-7.53 {is e editable} { + $var(e) editable +} {1} + +# Test: c_variable-7.54 +# Desc: number of children of e +gdbtk_test c_variable-7.54 {number of children of e} { + $var(e) numChildren +} {0} + +# Test: c_variable-7.55 +# Desc: children of e +gdbtk_test c_variable-7.55 {children of e} { + get_children e +} {} + +# Test: c_variable-7.60 +# Desc: create anone +gdbtk_test c_variable-7.60 {create anone} { + create_variable anone +} {0} + +# Test: c_variable-7.61 +# Desc: value of anone +gdbtk_test c_variable-7.61 {value of e} { + $var(e) value bar + $var(e) value +} {bar} + +# Test: c_variable-7.62 +# Desc: type of e +gdbtk_test c_variable-7.62 {type of e} { + $var(e) type +} {enum foo} + +# Test: c_variable-7.63 +# Desc: is e editable +gdbtk_test c_variable-7.63 {is e editable} { + $var(e) editable +} {1} + +# Test: c_variable-7.64 +# Desc: number of children of e +gdbtk_test c_variable-7.64 {number of children of e} { + $var(e) numChildren +} {0} + +# Test: c_variable-7.65 +# Desc: children of e +gdbtk_test c_variable-7.65 {children of e} { + get_children e +} {} + +# Test: c_variable-7.70 +# Desc: create anone +gdbtk_test c_variable-7.70 {try to create anone again (duplicate obj name} { + create_variable anone +} {1} + +# Test: c_variable-7.71 +# Desc: value of anone +gdbtk_test c_variable-7.71 {value of anone} { + $var(anone) value A + $var(anone) value +} {A} + +# Test: c_variable-7.72 +# Desc: type of anone +gdbtk_test c_variable-7.72 {type of anone} { + $var(anone) type +} {enum} + +# Test: c_variable-7.73 +# Desc: is anone editable +gdbtk_test c_variable-7.73 {is anone editable} { + $var(anone) editable +} {1} + +# Test: c_variable-7.74 +# Desc: number of children of anone +gdbtk_test c_variable-7.74 {number of children of anone} { + $var(anone) numChildren +} {0} + +# Test: c_variable-7.75 +# Desc: children of anone +gdbtk_test c_variable-7.75 {children of anone} { + get_children anone +} {} + +# Record fp +set fp [gdb_cmd "output/x \$fp"] +gdb_cmd {break incr_a} +gdb_cmd {continue} + +# Test: c_variable-7.80 +# Desc: stop in incr_a +gdbtk_test c_variable-7.80 {stop in incr_a} { + lindex [gdb_loc] 1 +} {incr_a} + +# Test: c_variable-7.81 +# Desc: Create variables in different scopes +gdbtk_test c_variable-7.81 {create variables in different scopes} { + set a1 [gdb_variable create -expr a] + set a2 [gdb_variable create -expr a -frame $fp] + + set vals {} + lappend vals [$a1 value] + lappend vals [$a2 value] + set vals +} {2 1} + +# Exit +# +gdbtk_test_done diff --git a/gdb/testsuite/gdb.gdbtk/configure b/gdb/testsuite/gdb.gdbtk/configure new file mode 100644 index 00000000000..c65cbd9d2a5 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/configure @@ -0,0 +1,900 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12.2 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12.2" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=defs + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +CC=${CC-cc} + +ac_aux_dir= +for ac_dir in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../../.. $srcdir/`cd $srcdir;pwd`/../../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:575: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:596: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:614: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set) 2>&1 | grep ac_space` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12.2" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/gdb/testsuite/gdb.gdbtk/configure.in b/gdb/testsuite/gdb.gdbtk/configure.in new file mode 100644 index 00000000000..4c408e8c828 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/configure.in @@ -0,0 +1,14 @@ +dnl Process this file file with autoconf to produce a configure script. +dnl This file is a shell script fragment that supplies the information +dnl necessary to tailor a template configure script into the configure +dnl script appropriate for this directory. For more information, check +dnl any existing configure script. + +AC_PREREQ(2.5) +AC_INIT(defs) + +CC=${CC-cc} +AC_SUBST(CC) +AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..) +AC_CANONICAL_SYSTEM +AC_OUTPUT(Makefile) diff --git a/gdb/testsuite/gdb.gdbtk/console.exp b/gdb/testsuite/gdb.gdbtk/console.exp new file mode 100644 index 00000000000..1d50c661ab6 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/console.exp @@ -0,0 +1,34 @@ +# +# Check if we have a display +# +if {![info exists ::env(DISPLAY)]} { + untested "No DISPLAY -- skipping test" +} else { + + if {$tracelevel} { + strace $tracelevel + } + + # + # test console window + # + set prms_id 0 + set bug_id 0 + + set testfile "simple" + set srcfile ${testfile}.c + set binfile ${objdir}/${subdir}/${testfile} + set r [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] + if { $r != "" } { + gdb_suppress_entire_file \ + "Testcase compile failed, so some tests in this file will automatically fail." + } + + # Start with a fresh gdbtk + gdb_exit + set results [gdbtk_start [file join $srcdir $subdir console.test]] + set results [split $results \n] + + # Analyze results + gdbtk_analyze_results $results +} diff --git a/gdb/testsuite/gdb.gdbtk/console.test b/gdb/testsuite/gdb.gdbtk/console.test new file mode 100644 index 00000000000..d24dd6b51eb --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/console.test @@ -0,0 +1,474 @@ +# Copyright (C) 1998, 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Keith Seitz (keiths@cygnus.com) + +# Read in the standard defs file + +if {![gdbtk_read_defs]} { + break +} + +global objdir test_ran +global console text +set console [ManagedWin::open Console] +set text [$console get_text] + +##### ##### +# # +# Helper functions for this module # +# # +##### ##### + +# console_command -- +# Invoke STRING as a command in the console window and +# return the result +proc console_command {string} { + global console text + + # Save current position + set line [lindex [split [$text index cmdmark] .] 0] + incr line 1 + + # Insert and invoke command + $text insert end $string + $console invoke + update + + # Get the result + set end [lindex [split [$text index cmdmark] .] 0] + incr end -1 + return [$text get $line.0 [list $end.0 lineend]] +} + +# get_cmd_line -- +# Return the command line +proc get_cmd_line {} { + global text + + update + set index [$text index cmdmark] + return [$text get [list $index linestart] [list $index lineend]] +} + +# clear_command_line -- +# Clear the command line +proc clear_command_line {} { + global text + $text delete {cmdmark + 1 char} insert +} + +##### ##### +# # +# CONSOLE TESTS # +# # +##### ##### + +# +# Miscellaneous tests +# + +# Test: console-misc-1 +# Desc: Change console prompt +gdbtk_test console-misc-1 {change console prompt} { + # Insert the "set prompt" command into the text widget + console_command {set prompt (test) } + + $text get {cmdmark linestart} {cmdmark lineend} +} {(test) } +if {$test_ran} { + console_command {set prompt (gdb) } +} + +# +# Paste tests +# + +# Test: console-paste-1 +# Desc: Paste the X selection into console window +gdbtk_test console-paste-1 {paste X text} { + # This is cheesy, but it works... Create a text widget + # which holds the current selection... + text .test_text + .test_text insert end "this is some pasted text" + .test_text tag add sel 1.0 {1.0 lineend} + + event generate $text <<Paste>> + get_cmd_line +} {(gdb) this is some pasted text} +if {$test_ran} { + destroy .test_text + clear_command_line +} + +# +# Test for errors +# + +# Test: console-error-1 +# Desc: Check if console window reports internal gdb errors +gdbtk_test console-error-1 {invoke unknown command} { + console_command {this_command_doesn't_exist} +} {Error: Undefined command: "this". Try "help". +} + +# +# History tests +# + +# Test: console-history-1.1 +# Desc: Exercise the up-history functionality +gdbtk_test console-history-1.1 {up history once} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + event generate $text <Up> + get_cmd_line +} {(gdb) help si} +if {$test_ran} { + clear_command_line +} + +# Test: console-history-1.2 +# Desc: Exercise the up-history functionality +gdbtk_test console-history-1.2 {up history twice} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + event generate $text <Up> + event generate $text <Up> + get_cmd_line +} {(gdb) help quit} +if {$test_ran} { + clear_command_line +} + +# Test: console-history-1.3 +# Desc: Exercise the up-history functionality +gdbtk_test console-history-1.3 {up history four times} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + + for {set i 0} {$i < 4} {incr i} { + event generate $text <Up> + } + get_cmd_line +} {(gdb) show remotedevice} +if {$test_ran} { + clear_command_line +} + +# Test: console-history-1.4 +# Desc: Exercise the up-history functionality +gdbtk_test console-history-1.4 {up fourteen times} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + for {set i 0} {$i < 14} {incr i} { + event generate $text <Up> + } + get_cmd_line +} {(gdb) show annotate} +if {$test_ran} { + clear_command_line +} + +# Test: console-history-1.5 +# Desc: Exercise the up-history search functionality +gdbtk_test console-history-1.5 {up search} { + # Add some commands into the command buffer + console_command {show height} + console_command {show annotate} + console_command {show complaints} + console_command {print main} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + + $text insert end "sh" + event generate $text <Shift-Up> + event generate $text <Shift-Up> + event generate $text <Shift-Up> + get_cmd_line +} {(gdb) show annotate} + + +# Test: console-history-1.6 +# Desc: Exercise the down-history search functionality +gdbtk_test console-history-1.6 {down search} { + event generate $text <Shift-Down> + event generate $text <Shift-Down> + get_cmd_line +} {(gdb) show remotelogbase} + +# Test: console-history-1.7 +# Desc: Down-history search to bottom +# We go back down until the original partialcommand is displayed +gdbtk_test console-history-1.7 {down search to bottom} { + event generate $text <Shift-Down> + event generate $text <Shift-Down> + get_cmd_line +} {(gdb) sh} + +# Test: console-history-1.8 +# Desc: Up-history search to top +# We go up until there are no matches +gdbtk_test console-history-1.8 {up search to top} { + for {set i 0} {$i < 100} {incr i} { + event generate $text <Shift-Up> + } + get_cmd_line +} {(gdb) show annotate} + +if {$test_ran} { + clear_command_line +} + +# Test: console-history-2.1 +# Desc: Exercise the down-history functionality +gdbtk_test console-history-2.1 {down once} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + + for {set i 0} {$i < 14} {incr i} { + event generate $text <Up> + } + event generate $text <Down> + get_cmd_line +} {(gdb) show complaints} +if {$test_ran} { + clear_command_line +} + +# Test: console-history-2.2 +# Desc: Exercise the down-history functionality +gdbtk_test console-history-2.2 {down twice} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + + for {set i 0} {$i < 14} {incr i} { + event generate $text <Up> + } + + event generate $text <Down> + event generate $text <Down> + get_cmd_line +} {(gdb) show confirm} +if {$test_ran} { + clear_command_line +} + +# Test: console-history-2.3 +# Desc: Exercise the down-history functionality +gdbtk_test console-history-2.3 {down four times} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + + for {set i 0} {$i < 14} {incr i} { + event generate $text <Up> + } + + for {set i 0} {$i < 4} {incr i} { + event generate $text <Down> + } + get_cmd_line +} {(gdb) show language} +if {$test_ran} { + clear_command_line +} + +# Test: console-history-2.4 +# Desc: Exercise the down-history functionality +gdbtk_test console-history-2.4 {down infinitely} { + # Add some commands into the command buffer + console_command {show annotate} + console_command {show complaints} + console_command {show confirm} + console_command {show height} + console_command {show language} + console_command {show print demangle} + console_command {show remotebaud} + console_command {show remotebreak} + console_command {show remotecache} + console_command {show remotedebug} + console_command {show remotedevice} + console_command {show remotelogbase} + console_command {help quit} + console_command {help si} + for {set i 0} {$i < 14} {incr i} { + event generate $text <Up> + } + + for {set i 0} {$i < 20} {incr i} { + event generate $text <Down> + } + get_cmd_line +} {(gdb) } +if {$test_ran} { + clear_command_line +} + +# +# gdb - gdbtk Interface Tests +# + +# Test: console-interface-1.1 +# Desc: Verify that a "file" command in the console window causes +# gdb to invoke the pre-/post-add-symbol hooks +set file_loaded 0 +gdbtk_test console-interface-1.1 {file command goes through hooks} { + global TEST1_RESULT TEST2_RESULT + + # This is really ugly, but its the only way to do this... + rename gdbtk_tcl_pre_add_symbol pre_add + rename gdbtk_tcl_post_add_symbol post_add + + proc gdbtk_tcl_pre_add_symbol {file} { + global TEST1_RESULT + + set TEST1_RESULT $file + pre_add $file + } + proc gdbtk_tcl_post_add_symbol {} { + global TEST2_RESULT + + set TEST2_RESULT ok + post_add + } + + # load a file and make sure we went through the pre/post_add_symbol hooks + set TEST1_RESULT {} + set TEST2_RESULT {} + set file [file join $objdir simple] + console_command "file $file" + if {$TEST1_RESULT != $file} { + set result "did not go through gdbtk_tcl_pre_add_symbol ($TEST1_RESULT)" + } elseif {$TEST2_RESULT != "ok"} { + set result "did not go through gdbtk_tcl_post_add_symbol" + } else { + set result {} + set file_loaded 1 + } + + set result +} {} +if {$test_ran} { + rename gdbtk_tcl_pre_add_symbol {} + rename gdbtk_tcl_post_add_symbol {} + rename pre_add gdbtk_tcl_pre_add_symbol + rename post_add gdbtk_tcl_post_add_symbol +} + +# +# Exit +# +gdbtk_test_done + +# Local variables: +# mode: tcl +# change-log-default-name: "ChangeLog-gdbtk" +# End: diff --git a/gdb/testsuite/gdb.gdbtk/cpp_variable.cc b/gdb/testsuite/gdb.gdbtk/cpp_variable.cc new file mode 100644 index 00000000000..deecc295a7f --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/cpp_variable.cc @@ -0,0 +1,33 @@ +#include "cpp_variable.h" + +static void do_simple_class_tests (void); + +int +VB::fvb_pub () {return 300 + vb_pub_int;} + +int +VB::vvb_pub () {return 400 + vb_pub_int;} + +int +V::f () {return 600 + v_pub_int;} + +int +V::vv () {return 400 + v_pub_int;} + +int +VC::fvc () {return 300 + vc_pub_int;} + +int +VC::vfvc () {return 100 + vc_pub_int;} + +main () +{ + do_simple_class_tests (); +} + +static void +do_simple_class_tests (void) +{ + V *v = new V; + V vv; +} diff --git a/gdb/testsuite/gdb.gdbtk/cpp_variable.exp b/gdb/testsuite/gdb.gdbtk/cpp_variable.exp new file mode 100644 index 00000000000..ed5ca35dc67 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/cpp_variable.exp @@ -0,0 +1,34 @@ +# +# Check if we have a display +# +if {![info exists ::env(DISPLAY)]} { + untested "No DISPLAY -- skipping test" +} else { + + if {$tracelevel} { + strace $tracelevel + } + + # + # test variable API + # + set prms_id 0 + set bug_id 0 + + set testfile "cpp_variable" + set srcfile ${testfile}.cc + set binfile ${objdir}/${subdir}/${testfile} + set r [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] + if { $r != "" } { + gdb_suppress_entire_file \ + "Testcase compile failed, so some tests in this file will automatically fail." + } + + # Start with a fresh gdbtk + gdb_exit + set results [gdbtk_start [file join $srcdir $subdir ${testfile}.test]] + set results [split $results \n] + + # Analyze results + gdbtk_analyze_results $results +} diff --git a/gdb/testsuite/gdb.gdbtk/cpp_variable.h b/gdb/testsuite/gdb.gdbtk/cpp_variable.h new file mode 100644 index 00000000000..40fda99a4dd --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/cpp_variable.h @@ -0,0 +1,54 @@ +struct _foo +{ + int a[10]; + char *p; +}; + +class VA +{ + public: + int va_pub_int; + char *va_pub_charp; + + private: + int va_priv_int; + char *va_priv_charp; + + protected: + struct _foo bar; +}; + +class VB +{ + public: + int vb_pub_int; + + int fvb_pub (); + virtual int vvb_pub (); + + private: + int vb_priv_int; + char *vb_priv_charp; +}; + +class VC +{ + public: + int vc_pub_int; + + int fvc (); + virtual int vfvc (); +}; + +class V : public VA, public VB, public VC +{ + public: + int f (); + virtual int vv (); + int v_pub_int; + char *v_pub_charp; + + private: + int v_priv_int; + char *v_priv_charp; +}; diff --git a/gdb/testsuite/gdb.gdbtk/cpp_variable.test b/gdb/testsuite/gdb.gdbtk/cpp_variable.test new file mode 100644 index 00000000000..5f9c2732fd2 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/cpp_variable.test @@ -0,0 +1,562 @@ +# Copyright (C) 1998 Cygnus Solutions +# +# This Program Is Free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Keith Seitz (keiths@cygnus.com) + +# Read in the standard defs file +if {![gdbtk_read_defs]} { + break +} + +global objdir test_ran +global tcl_platform + +# Load in a file +if {$tcl_platform(platform) == "windows"} { + set program [file join $objdir cpp_variable.exe] +} else { + set program [file join $objdir cpp_variable] +} + +# This isn't a test case, since if this fails, we're hosed. +if {[catch {gdb_cmd "file $program"} t]} { + # an error occured loading the file + gdbtk_test_error "loading \"$program\": $t" +} + +# The variables that are created are stored in an array called "var". + +# proc to tell us which of the variables are changed/out of scope +proc check_update {} { + global var + + set changed {} + set unchanged {} + set out {} + #FIXME: Should get a list of root variables instead of using the array + foreach ind [array names var] { + set changed [concat $changed [$var($ind) update]] + } + + foreach ind [array names var] { + set ix [lsearch -exact $changed $var($ind)] + if {$ix < 0} { + lappend unchanged $var($ind) + } + } + + return [list $changed $unchanged $out] +} + +# proc to create a variable +proc create_variable {expr} { + global var + + set err [catch {gdb_variable create "$expr" -expr $expr} v] + if {!$err} { + set var($expr) $v + } + + return $err +} + +# proc to get the children +# Children are stored in the global "var" as +# PARENT.child. So for struct _foo {int a; int b} bar;, +# the children returned are {a b} and var(bar.a) and var(bar.b) +# map the actual objects to their names. +proc get_children {parent} { + global var + + set kiddies [$var($parent) children] + set children {} + foreach child $kiddies { + set name [lindex [split $child .] end] + lappend children $name + set var($parent.$name) $child + } + + return $children +} + +proc delete_variable {varname} { + global var + + if {[info exists var($varname)]} { + # This has to be caught, since deleting a parent + # will erase all children. + $var($varname) delete + set vars [array names var $varname*] + foreach v $vars { + if {[info exists var($v)]} { + unset var($v) + } + } + } +} + +# Compare the values of variable V in format FMT with value of OBJ +# with gdb's value. +proc cppvalue {obj v fmt} { + global var + global _test + + puts $_test(logfile) "obj=$obj v=$v fmt=$fmt" + puts $_test(logfile) "var(\$obj)=$var($obj)" + + set value [$var($obj) value] + set gdb [gdb_cmd "output/$fmt $v"] + puts $_test(logfile) "output/$fmt $v" + if {$value == $gdb} { + puts $_test(logfile) "gdbtk: $value == gdb: $gdb" + set result ok + } else { + set result $v + puts $_test(logfile) "gdbtk: $value <> gdb: $gdb" + } + + return $result +} + +proc delete_all_variables {} { + global var + + foreach variable [array names var] { + delete_variable $variable + } +} + +##### ##### +# # +# Simple Class Tests # +# # +##### ##### + +# run to "do_simple_class_tests" +gdb_cmd "break do_simple_class_tests" +gdb_cmd "run" + +# Test: cpp_variable-1.1 +# Desc: stopped in do_simple_class_tests +gdbtk_test cpp_variable-1.1 {stopped in do_simple_class_tests} { + lindex [gdb_loc] 1 +} {do_simple_class_tests(void)} + +# Test: cpp_variable-1.2 +# Desc: create variable v +gdbtk_test cpp_variable-1.2 {create variable v} { + create_variable v +} {0} + +# Test: cpp_variable-1.3 +# Desc: number of children of v +gdbtk_test cpp_variable-1.3 {number of children of v} { + $var(v) numChildren +} {5} + +# Test: cpp_variable-1.4a +# Desc: children of v +gdbtk_test cpp_variable-1.4a {children of v} { + get_children v +} {VA VB VC public private} + +# Test: cpp_variable-1.4b +# Desc: public children of v +gdbtk_test cpp_variable-1.4b {public children of v} { + get_children v.public +} {v_pub_int v_pub_charp} + +# Test: cpp_variable-1.4c +# Desc: private children of v +gdbtk_test cpp_variable-1.4c {private children of v} { + get_children v.private +} {v_priv_int v_priv_charp} + +# Test: cpp_variable-1.5 +# Desc: type of v +gdbtk_test cpp_variable-1.5 {type of v} { + $var(v) type +} {V *} + +# Test: cpp_variable-1.6 +# Desc: format of v +gdbtk_test cpp_variable-1.6 {format of v} { + $var(v) format +} {natural} + +set value [$var(v) value] + +# Step over "V *v = new V;" +gdb_cmd "next" + +# Test: cpp_variable-1.7 +# Desc: check value of v changed +gdbtk_test cpp_variable-1.7 {check value of v changed} { + check_update +} {{v v.public.v_pub_int v.public.v_pub_charp v.private.v_priv_int v.private.v_priv_charp} {v.VB v.VC v.private v.public v.VA} {}} + +# Test: cpp_variable-1.8 +# Desc: check values of v +gdbtk_test cpp_variable-1.8 {check values of v} { + set new [$var(v) value] + expr {$new != $value} +} {1} + +# Test: cpp_variable-1.9 +# Desc: v editable +gdbtk_test cpp_variable-1.9 {v editable} { + $var(v) editable +} {1} + +##### ##### +# # +# Children of v tests # +# # +##### ##### + +# Test: cpp_variable-2.1 +# Desc: type of v.v_pub_int +gdbtk_test cpp_variable-2.1 {type of v.v_pub_int} { + $var(v.public.v_pub_int) type +} {int} + +# Test: cpp_variable-2.2 +# Desc: format of v.v_pub_int +gdbtk_test cpp_variable-2.2 {format of v.v_pub_int} { + $var(v.public.v_pub_int) format +} {natural} + +gdb_cmd "set variable v.v_pub_int=2112" + +# Test: cpp_variable-2.3 +# Desc: value of v.v_pub_int changed +gdbtk_test cpp_variable-2.3 {value of v.v_pub_int changed} { + check_update +} {v.public.v_pub_int {v.private.v_priv_charp v.VB v.private.v_priv_int v.VC v.public.v_pub_charp v v.private v.public v.VA} {}} + +# Test: cpp_variable-2.4 +# Desc: value of v.v_pub_int +gdbtk_test cpp_variable-2.4 {value of v.v_pub_int} { + $var(v.public.v_pub_int) value +} {2112} + +# Test: cpp_variable-2.5 +# Desc: changed format of v.v_pub_int +gdbtk_test cpp_variable-2.5 {changed format of v.v_pub_int} { + $var(v.public.v_pub_int) format octal + $var(v.public.v_pub_int) format +} {octal} + +# Test: cpp_variable-2.6 +# Desc: value of v.v_pub_int with new format +gdbtk_test cpp_variable-2.6 {value of v.v_pub_int with new format} { + $var(v.public.v_pub_int) value +} {04100} + +# Test: cpp_variable-2.7 +# Desc: change value of v.v_pub_int (decimal) +gdbtk_test cpp_variable-2.7 {change value of v.v_pub_int (decimal)} { + $var(v.public.v_pub_int) value 3 + cppvalue v.public.v_pub_int v.v_pub_int o +} {ok} + +# Test: cpp_variable-2.8 +# Desc: change value of v.v_pub_int (hexadecimal) +gdbtk_test cpp_variable-2.8 {change value of v.v_pub_int (hexadecimal)} { + $var(v.public.v_pub_int) value 0x21 + cppvalue v.public.v_pub_int v.v_pub_int o +} {ok} + +# Test: cpp_variable-2.9 +# Desc: number of children of v_pub_int +gdbtk_test cpp_variable-2.9 {number of children of v_pub_int} { + $var(v.public.v_pub_int) numChildren +} {0} + +# Test: cpp_variable-2.10 +# Desc: children of v.v_pub_int +gdbtk_test cpp_variable-2.10 {children of v.v_pub_int} { + get_children v.public.v_pub_int +} {} + +# Test: cpp_variable-2.11 +# Desc: v.v_pub_int editable +gdbtk_test cpp_variable-2.11 {v.v_pub_int editable} { + $var(v.public.v_pub_int) editable +} {1} + +# Test: cpp_variable-2.21 +# Desc: type of v.v_priv_charp +gdbtk_test cpp_variable-2.21 {type of v.v_priv_charp} { + $var(v.private.v_priv_charp) type +} {char *} + +# Test: cpp_variable-2.22 +# Desc: format of v.v_priv_charp +gdbtk_test cpp_variable-2.22 {format of v.v_priv_charp} { + $var(v.private.v_priv_charp) format +} {natural} + +gdb_cmd "set variable v.v_priv_charp=2112" + +# Test: cpp_variable-2.23 +# Desc: value of v.v_priv_charp changed +gdbtk_test cpp_variable-2.23 {value of v.v_priv_charp changed} { + check_update +} {v.private.v_priv_charp {v.VB v.private.v_priv_int v.VC v.public.v_pub_charp v v.public.v_pub_int v.private v.public v.VA} {}} + +# Test: cpp_variable-2.24 +# Desc: value of v.v_priv_charp +gdbtk_test cpp_variable-2.24 {value of v.v_priv_charp} { + $var(v.private.v_priv_charp) format hexadecimal + $var(v.private.v_priv_charp) value +} {0x840} + +# Test: cpp_variable-2.25 +# Desc: changed format of v.v_priv_charp +gdbtk_test cpp_variable-2.25 {changed format of v.v_priv_charp} { + $var(v.private.v_priv_charp) format octal + $var(v.private.v_priv_charp) format +} {octal} + +# Test: cpp_variable-2.26 +# Desc: value of v.v_priv_charp with new format +gdbtk_test cpp_variable-2.26 {value of v.v_priv_charp with new format} { + $var(v.private.v_priv_charp) value +} {04100} + +# Test: cpp_variable-2.27 +# Desc: change value of v.v_priv_charp (decimal) +gdbtk_test cpp_variable-2.27 {change value of v.v_priv_charp (decimal)} { + $var(v.private.v_priv_charp) value 3 + cppvalue v.private.v_priv_charp v.v_priv_charp o +} {ok} + +# Test: cpp_variable-2.28 +# Desc: change value of v.v_priv_charp (hexadecimal) +gdbtk_test cpp_variable-2.28 {change value of v.v_priv_charp (hexadecimal)} { + $var(v.private.v_priv_charp) value 0x21 + cppvalue v.private.v_priv_charp v.v_priv_charp o +} {ok} + +# Test: cpp_variable-2.29 +# Desc: number of children of v_priv_charp +gdbtk_test cpp_variable-2.29 {number of children of v_priv_charp} { + $var(v.private.v_priv_charp) numChildren +} {0} + +# Test: cpp_variable-2.30 +# Desc: children of v.v_priv_charp +gdbtk_test cpp_variable-2.30 {children of v.v_priv_charp} { + get_children v.private.v_priv_charp +} {} + +# Test: cpp_variable-2.31 +# Desc: v.v_priv_int editable +gdbtk_test cpp_variable-2.31 {v.v_priv_int editable} { + $var(v.private.v_priv_int) editable +} {1} + +# Test: cpp_variable-2.41 +# Desc: type of v.VA +gdbtk_test cpp_variable-2.41 {type of v.VA} { + $var(v.VA) type +} {VA} + +# Test: cpp_variable-2.42 +# Desc: format of v.VA +gdbtk_test cpp_variable-2.42 {format of v.VA} { + $var(v.VA) format +} {natural} + +# Test: cpp_variable-2.43 +# Desc: value of v.VA changed +gdbtk_test cpp_variable-2.43 {value of v.VA changed} { + check_update +} {{} {v.private.v_priv_charp v.VB v.private.v_priv_int v.VC v.public.v_pub_charp v v.public.v_pub_int v.private v.public v.VA} {}} + +# Test: cpp_variable-2.44 +# Desc: value of v.VA +gdbtk_test cpp_variable-2.44 {value of v.VA} { + $var(v.VA) value +} {{...}} + +# Test: cpp_variable-2.45 +# Desc: changed format of v.VA +gdbtk_test cpp_variable-2.45 {changed format of v.VA} { + $var(v.VA) format octal + $var(v.VA) format +} {octal} + +# Test: cpp_variable-2.46 +# Desc: value of v.VA with new format +gdbtk_test cpp_variable-2.46 {value of v.VA with new format} { + $var(v.VA) value +} {{...}} + +# Test: cpp_variable-2.47 +# Desc: number of children of VA +gdbtk_test cpp_variable-2.47 {number of children of VA} { + $var(v.VA) numChildren +} {3} + +# Test: cpp_variable-2.48a +# Desc: children of v.VA +gdbtk_test cpp_variable-2.48a {children of v.VA} { + get_children v.VA +} {public private protected} + +# Test: cpp_variable-2.48b +# Desc: public children of v.VA +gdbtk_test cpp_variable-2.48b {children of v.VA} { + get_children v.VA.public +} {va_pub_int va_pub_charp} + +# Test: cpp_variable-2.48c +# Desc: private children of v.VA +gdbtk_test cpp_variable-2.48c {children of v.VA} { + get_children v.VA.private +} {va_priv_int va_priv_charp} + +# Test: cpp_variable-2.48d +# Desc: protected children of v.VA +gdbtk_test cpp_variable-2.48d {children of v.VA} { + get_children v.VA.protected +} {bar} + +# Test: cpp_variable-2.49 +# Desc: v.VA editable +gdbtk_test cpp_variable-2.49 {v.VA editable} { + $var(v.VA) editable +} {0} + +# Test: cpp_variable-2.61 +# Desc: type of v.VB +gdbtk_test cpp_variable-2.61 {type of v.VB} { + $var(v.VB) type +} {VB} + +# Test: cpp_variable-2.62 +# Desc: format of v.VB +gdbtk_test cpp_variable-2.62 {format of v.VB} { + $var(v.VB) format +} {natural} + +# Test: cpp_variable-2.63 +# Desc: value of v.VB changed +gdbtk_test cpp_variable-2.63 {value of v.VB changed} { + check_update +} {{} {v.VA.protected v.VA.private v.VA.public.va_pub_int v.private.v_priv_int v v.public.v_pub_int v.VA.public.va_pub_charp v.private.v_priv_charp v.VA.public v.public.v_pub_charp v.VA.private.va_priv_int v.VA v.public v.VB v.VC v.VA.protected.bar v.VA.private.va_priv_charp v.private} {}} + +# Test: cpp_variable-2.64 + # Desc: value of v.VB +gdbtk_test cpp_variable-2.64 {value of v.VB} { + $var(v.VB) value +} {{...}} + +# Test: cpp_variable-2.65 +# Desc: changed format of v.VB +gdbtk_test cpp_variable-2.65 {changed format of v.VB} { + $var(v.VB) format octal + $var(v.VB) format +} {octal} + +# Test: cpp_variable-2.66 +# Desc: value of v.VB with new format +gdbtk_test cpp_variable-2.66 {value of v.VB with new format} { + $var(v.VB) value +} {{...}} + +# Note: The next two tests show whether or not the logic +# concerning vptr tables is working. +# Test: cpp_variable-2.67 +# Desc: number of children of VB +gdbtk_test cpp_variable-2.67 {number of children of VB} { + $var(v.VB) numChildren +} {2} + +# Test: cpp_variable-2.68a +# Desc: children of v.VB +gdbtk_test cpp_variable-2.68a {children of v.VB} { + get_children v.VB +} {public private} + +# Test: cpp_variable-2.68b +# Desc: public children of v.VB +gdbtk_test cpp_variable-2.68b {children of v.VB} { + get_children v.VB.public +} {vb_pub_int} + +# Test: cpp_variable-2.68c +# Desc: private children of v.VB +gdbtk_test cpp_variable-2.68c {children of v.VB} { + get_children v.VB.private +} {vb_priv_int vb_priv_charp} + +# Test: cpp_variable-2.69 +# Desc: v.VB editable +gdbtk_test cpp_variable-2.69 {v.VB editable} { + $var(v.VB) editable +} {0} + +# Test: cpp_variable-2.70 +# Desc: v.VB.public editable +gdbtk_test cpp_variable-2.70 {v.VB.public editable} { + $var(v.VB.public) editable +} {0} + +# Test: cpp_variable-2.71 +# Desc: v.VB.vb_pub_int editable +gdbtk_test cpp_variable-2.71 {v.VB.vb_pub_int editable} { + $var(v.VB.public.vb_pub_int) editable +} {1} + +gdb_cmd "set variable v.vb_pub_int=2112" + +# Test: cpp_variable-2.72 +# Desc: value of v.vb_pub_int changed +gdbtk_test cpp_variable-2.72 {value of v.vb_pub_int changed} { + check_update +} {v.VB.public.vb_pub_int {v.VB.public v.VA.protected v.VA.private v.VB.private.vb_priv_int v.VB.private v.VA.public.va_pub_int v.private.v_priv_int v v.public.v_pub_int v.VB.private.vb_priv_charp v.VA.public.va_pub_charp v.private.v_priv_charp v.VA.public v.public.v_pub_charp v.VA.private.va_priv_int v.VA v.public v.VB v.VC v.VA.protected.bar v.VA.private.va_priv_charp v.private} {}} + +# Test: cpp_variable-2.73 +# Desc: value of v.VB.vb_pub_int +gdbtk_test cpp_variable-2.73 {changed value of v.vb_pub_int} { + $var(v.VB.public.vb_pub_int) value +} {2112} + +# Test: cpp_variable-2.74 +# Desc: change value of v.VB.vb_pub_int +gdbtk_test cpp_variable-2.74 {change value of v.VB.public.vb_pub_int} { + $var(v.VB.public.vb_pub_int) value 3 + cppvalue v.VB.public.vb_pub_int v.vb_pub_int d +} {ok} + +# Test: cpp_variable-2.75 +# Desc: value of v.VB.vb_pub_int +gdbtk_test cpp_variable-2.75 {changed value of v.VB.public.vb_pub_int} { + $var(v.VB.public.vb_pub_int) value +} {3} + + +# Exit +# +gdbtk_test_done + + diff --git a/gdb/testsuite/gdb.gdbtk/defs b/gdb/testsuite/gdb.gdbtk/defs new file mode 100644 index 00000000000..a4f20c60f81 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/defs @@ -0,0 +1,218 @@ +# This file contains support code for the gdbtk test suite. +# +# Based on the Tcl testsuite support code, portions of this file +# are Copyright (c) 1990-1994 The Regents of the University of California and +# Copyright (c) 1994-1996 Sun Microsystems, Inc. +# +global srcdir _test env srcdir objdir + +if {![info exists srcdir]} { + if {[info exists env(SRCDIR)]} { + set srcdir $env(SRCDIR) + } else { + set srcdir . + } +} + +if {![info exists objdir]} { + if {[info exists env(OBJDIR)]} { + set objdir $env(OBJDIR) + } elseif {$_test(interactive)} { + # If running interactively, assume that the objdir is + # relative to the executable's location + set objdir [file join [file dirname [info nameofexecutable]] testsuite gdb.gdbtk] + } else { + set objdir . + } +} + +if {![info exists _test(verbose)]} { + if {[info exists env(GDBTK_VERBOSE)]} { + set _test(verbose) $env(GDBTK_VERBOSE) + } else { + set _test(verbose) + } +} +if {![info exists _test(tests)]} { + + if {[info exists env(GDBTK_TESTS)]} { + set _test(tests) $env(GDBTK_TESTS) + } else { + set _test(tests) {} + } +} + +if {[info exists env(GDBTK_LOGFILE)]} { + set _test(logfile) [open $env(GDBTK_LOGFILE) a+] + fconfigure $_test(logfile) -buffering none +} else { + set _test(logfile) {} +} + +# Informs gdbtk internals that testsuite is running. An example +# where this is needed is the window manager, which must place +# all windows at some place on the screen so that the system's +# window manager does not interfere. This is reset in gdbtk_test_done. +set env(GDBTK_TEST_RUNNING) 1 + +proc gdbtk_print_verbose {status name description script code answer} { + global _test + + switch $code { + 0 { + set code_words {} + } + 1 { + set code_words "Test generated error: $answer" + } + + 2 { + set code_words "Test generated return exception; result was: $answer" + } + + 3 { + set code_words "Test generated break exception" + } + + 4 { + set code_words "Test generated continue exception" + } + + 5 { + set code_words "Test generated exception $code; message was:$answer" + } + } + + if {$_test(verbose) > 1 \ + || ($_test(verbose) != 1 && ($status == "ERROR" || $status == "FAIL"))} { + # Printed when user verbose mode (verbose > 1) or an error/failure occurs + # not running the testsuite (dejagnu) + puts stdout "\n" + puts stdout "==== $name $description" + puts stdout "==== Contents of test case:" + puts stdout "$script" + if {$code_words != ""} { + puts stdout $code_words + } + puts stdout "==== Result was:" + puts stdout "$answer" + } elseif {$_test(verbose)} { + # Printed for the testsuite (verbose = 1) + puts stdout "[list $status $name $description $code_words]" + + if {$_test(logfile) != ""} { + puts $_test(logfile) "\n" + puts $_test(logfile) "==== $name $description" + puts $_test(logfile) "==== Contents of test case:" + puts $_test(logfile) "$script" + if {$code_words != ""} { + puts $_test(logfile) $code_words + } + puts $_test(logfile) "==== Result was:" + puts $_test(logfile) "$answer" + } + } +} + +# gdbtk_test +# +# This procedure runs a test and prints an error message if the +# test fails. +# +# Arguments: +# name - Name of test, in the form foo-1.2. +# description - Short textual description of the test, to +# help humans understand what it does. +# script - Script to run to carry out the test. It must +# return a result that can be checked for +# correctness. +# answer - Expected result from script. + +proc gdbtk_test {name description script answer} { + global _test test_ran + + set test_ran 0 + if {[string compare $_test(tests) ""] != 0} then { + set ok 0 + foreach test $_test(tests) { + if [string match $test $name] then { + set ok 1 + break + } + } + if !$ok then return + } + + set code [catch {uplevel $script} result] + set test_ran 1 + if {$code != 0} { + # Error + gdbtk_print_verbose ERROR $name $description $script \ + $code $result + } elseif {[string compare $result $answer] == 0} { + if {[string index $name 0] == "*"} { + # XPASS + set HOW XPASS + } else { + set HOW PASS + } + + if {$_test(verbose)} { + gdbtk_print_verbose $HOW $name $description $script \ + $code $result + if {$_test(verbose) != 1} { + puts stdout "++++ $name ${HOW}ED" + } + } + if {$_test(logfile) != ""} { + puts $_test(logfile) "++++ $name ${HOW}ED" + } + } else { + if {[string index $name 0] == "*"} { + # XFAIL + set HOW XFAIL + } else { + set HOW FAIL + } + + gdbtk_print_verbose $HOW $name $description $script \ + $code $result + if {$_test(verbose) != 1} { + puts stdout "---- Result should have been:" + puts stdout "$answer" + puts stdout "---- $name ${HOW}ED" + } + if {$_test(logfile) != ""} { + puts $_test(logfile) "---- Result should have been:" + puts $_test(logfile) "$answer" + puts $_test(logfile) "---- $name ${HOW}ED" + } + } +} + +proc gdbtk_dotests {file args} { + global _test + set savedTests $_test(tests) + set _test(tests) $args + source $file + set _test(tests) $savedTests +} + +proc gdbtk_test_done {} { + global _test env + + if {$_test(logfile) != ""} { + close $_test(logfile) + } + + set env(GDBTK_TEST_RUNNING) 0 + if {![info exists _test(interactive)] || !$_test(interactive)} { + gdb_force_quit + } +} + +proc gdbtk_test_error {desc} { + set desc [join [split $desc \n] |] + puts "ERROR \{$desc\} \{\} \{\}" + gdbtk_test_done +} diff --git a/gdb/testsuite/gdb.gdbtk/simple.c b/gdb/testsuite/gdb.gdbtk/simple.c new file mode 100644 index 00000000000..b35cd58851b --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/simple.c @@ -0,0 +1,20 @@ +int +main(int argc, char * argv[]) +{ + int i; + char *a; + char *b = "abc"; + long foo; + + a = (char *) malloc (300); + + for (i=0; i < 50; i++) + { + int j = i % 3; + int k = 3 - j; + strncpy (a[i], b[k], j); + foo = (long) j * k / i + 2 * k * k * k; + } + return 0; +} + diff --git a/gdb/testsuite/gdb.gdbtk/srcwin.exp b/gdb/testsuite/gdb.gdbtk/srcwin.exp new file mode 100644 index 00000000000..e3dc07dff87 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/srcwin.exp @@ -0,0 +1,59 @@ +# +# Check if we have a display +# +if {![info exists ::env(DISPLAY)]} { + untested "No DISPLAY -- skipping test" +} else { + if {$tracelevel} { + strace $tracelevel + } + + # + # test source window + # + set prms_id 0 + set bug_id 0 + + set testfile "list" + set binfile $objdir/$subdir/$testfile + set r [gdb_compile "$srcdir/gdb.base/list0.c $srcdir/gdb.base/list1.c" "$binfile" executable debug] + if { $r != "" } { + gdb_suppress_entire_file \ + "Testcase compile failed, so some tests in this file will automatically fail." + } + + # Start with a fresh gdbtk + gdb_exit + set results [gdbtk_start [file join $srcdir $subdir srcwin.test]] + set results [split $results \n] + # Analyze results + gdbtk_analyze_results $results + + # move file with "main" out of the way + file rename $srcdir/gdb.base/list0.c $srcdir/gdb.base/list0.c.save + # run slightly different set of tests + gdb_exit + set results [gdbtk_start [file join $srcdir $subdir srcwin2.test]] + set results [split $results \n] + #restore file + file rename $srcdir/gdb.base/list0.c.save $srcdir/gdb.base/list0.c + # Analyze results + gdbtk_analyze_results $results + + set r [gdb_compile "$srcdir/gdb.base/list0.c $srcdir/gdb.base/list1.c" "$binfile" executable ""] + if { $r != "" } { + gdb_suppress_entire_file \ + "Testcase compile failed, so some tests in this file will automatically fail." + } + # run slightly different set of tests + gdb_exit + set results [gdbtk_start [file join $srcdir $subdir srcwin3.test]] + set results [split $results \n] + # Analyze results + gdbtk_analyze_results $results +} + +# Local variables: +# mode: tcl +# change-log-default-name: "ChangeLog-gdbtk" +# End: diff --git a/gdb/testsuite/gdb.gdbtk/srcwin.test b/gdb/testsuite/gdb.gdbtk/srcwin.test new file mode 100644 index 00000000000..bc1ec9d78a2 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/srcwin.test @@ -0,0 +1,1221 @@ +# Copyright (C) 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Martin Hunt (hunt@cygnus.com) + +# Read in the standard defs file + +if {![gdbtk_read_defs]} { + break +} + +global objdir srcdir + + +# move the pointer to the center of the bbox relative to $win +proc move_mouse_to {win bbox} { + if {[llength $bbox] != 4} { + return 0 + } + set x [expr [lindex $bbox 0] + [lindex $bbox 2] / 2] + set y [expr [lindex $bbox 1] + [lindex $bbox 3] / 2] + warp_pointer . [winfo rootx $win] [winfo rooty $win] + + set nx 0 + set ny 0 + + while {$nx != $x || $ny != $y} { + if {$nx < $x} {incr nx} + if {$ny < $y} {incr ny} + warp_pointer $win $nx $ny + } + return 1 +} + +proc click {win bbox event} { + if {![move_mouse_to $win $bbox]} { + return 0 + } + update + + set x [expr [lindex $bbox 0] + [lindex $bbox 2] / 2] + set y [expr [lindex $bbox 1] + [lindex $bbox 3] / 2] + + if {[catch {event generate $win $event -x $x -y $y} result]} { + return 0 + } + return 1 +} + + +##### ##### +# # +# SECTION 1: Mode Tests # +# # +##### ##### + +# Load the test executable +if {$tcl_platform(platform) == "windows"} { + set file [file join $objdir list.exe] +} else { + set file [file join $objdir list] +} + +# This isn't a test case, since if this fails, we're hosed. +if {[catch {gdb_cmd "file $file" 1} t]} { + # an error occured loading the file + gdbtk_test_error "loading \"$file\": $t" +} + +set srcwin [ManagedWin::open SrcWin] +set stw [$srcwin test_get twin] +set twin [$stw test_get twin] + +# get things started +gdb_cmd "break main" +run_executable + +# Test: srcwin-1.1 +# Desc: Check for something in source window +gdbtk_test srcwin-1.1 "source window has contents" { + set file1(source) [$twin get 1.0 end] + expr {![string compare $file1(source) ""]} +} {0} + + +# Test: srcwin-1.2 +# Desc: source->assembly mode change +gdbtk_test srcwin-1.2 "source->assembly mode change" { + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + set file1(assembly) [$twin get 1.0 end] + expr {![string compare $file1(source) $file1(assembly)]} +} {0} + +# Test: srcwin-1.3 +# Desc: assembly->mixed mode change +gdbtk_test srcwin-1.3 "assembly->mixed mode change" { + $srcwin mode "" MIXED + set twin [$stw test_get twin] + set file1(mixed) [$twin get 1.0 end] + expr {![string compare $file1(mixed) $file1(assembly)]} +} {0} + +# Test: srcwin-1.4 +# Desc: mixed->src+asm mode change +gdbtk_test srcwin-1.4 "mixed->src+asm mode change" { + $srcwin mode "" SRC+ASM + set twin [$stw test_get twin] + set bwin [$stw test_get bwin] + set s [$twin get 1.0 end] + set a [$bwin get 1.0 end] + list [string compare $a $file1(assembly)] [string compare $s $file1(source)] [winfo ismapped $bwin] +} {0 0 1} + +# Test: srcwin-1.5 +# Desc: src+asm->source mode change +gdbtk_test srcwin-1.5 "src+asm->source mode change" { + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + set bwin [$stw test_get bwin] + list [string compare $file1(source) $a] [winfo ismapped $bwin] +} {0 0} + +# Test: srcwin-1.6 +# Desc: source->mixed mode change +gdbtk_test srcwin-1.6 "source->mixed mode change" { + $srcwin mode "" MIXED + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + string compare $file1(mixed) $a +} {0} + +# Test: srcwin-1.7 +# Desc: mixed->source mode change +gdbtk_test srcwin-1.7 "mixed->source mode change" { + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + string compare $file1(source) $a +} {0} + +# Test: srcwin-1.8 +# Desc: source->src+asm mode change +gdbtk_test srcwin-1.8 "source->src+asm mode change" { + $srcwin mode "" SRC+ASM + set twin [$stw test_get twin] + set bwin [$stw test_get bwin] + set s [$twin get 1.0 end] + set a [$bwin get 1.0 end] + list [string compare $a $file1(assembly)] [string compare $s $file1(source)] [winfo ismapped $bwin] +} {0 0 1} + +# Test: srcwin-1.9 +# Desc: src+asm->assembly mode change +gdbtk_test srcwin-1.9 "src+asm->assembly mode change" { + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + string compare $file1(assembly) $a +} {0} + +# Test: srcwin-1.10 +# Desc: assembly->src+asm mode change +gdbtk_test srcwin-1.10 "assembly->src+asm mode change" { + $srcwin mode "" SRC+ASM + set twin [$stw test_get twin] + set bwin [$stw test_get bwin] + set s [$twin get 1.0 end] + set a [$bwin get 1.0 end] + list [string compare $a $file1(assembly)] [string compare $s $file1(source)] [winfo ismapped $bwin] +} {0 0 1} + +# Test: srcwin-1.11 +# Desc: src+asm->mixed mode change +gdbtk_test srcwin-1.11 "src+asm->mixed mode change" { + $srcwin mode "" MIXED + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + set bwin [$stw test_get bwin] + expr {[string compare $file1(mixed) $a] || + [winfo ismapped $bwin]} +} {0} + +# Test: srcwin-1.12 +# Desc: mixed->assembly mode change +gdbtk_test srcwin-1.12 "mixed->assembly mode change" { + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + string compare $file1(assembly) $a +} {0} + +# Test: srcwin-1.13 +# Desc: assembly->source mode change +gdbtk_test srcwin-1.13 "assembly->source mode change" { + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + string compare $file1(source) $a +} {0} + + +##### ##### +# # +# SECTION 2: Basic Operations # +# # +##### ##### + +# Test: srcwin-2.1 +# Desc: check contents of filename combobox +gdbtk_test srcwin-2.1 "check contents of filename combobox" { + set statbar [$srcwin test_get _statbar] + set names [$statbar.name listget 0 end] + set r 0 + foreach f {list0.c list1.c list0.h} { + if {[lsearch $names $f] != -1} { + incr r + } + } + set r +} {3} + +# Test: srcwin-2.2 +# Desc: check contents of function combobox +gdbtk_test srcwin-2.2 "check contents of function combobox" { + set names [$statbar.func listget 0 end] + set r 0 + foreach f {main foo unused} { + if {[lsearch $names $f] != -1} { + incr r + } + } + set r +} {3} + +# Test: srcwin-2.3 +# Desc: goto filename +gdbtk_test srcwin-2.3 "goto filename" { + set func [$srcwin test_get _name 1] + $func "" list1.c + set twin [$stw test_get twin] + set file2(source) [$twin get 1.0 end] + expr {![string compare $file1(source) $file2(source)]} +} {0} + +# Test: srcwin-2.4 +# Desc: check contents of function combobox +gdbtk_test srcwin-2.4 "check contents of function combobox" { + set names [$statbar.func listget 0 end] + set r 0 + foreach f {bar long_line oof unused} { + if {[lsearch $names $f] != -1} { + incr r + } + } + set r +} {4} + +# Test: srcwin-2.5 +# Desc: function combobox entry field should be empty after switching to a new file +gdbtk_test srcwin-2.5 "function combobox entry field should be empty" { + set names [$statbar.func get] + string length $names +} {0} + +# Test: srcwin-2.6 +# Desc: goto function +gdbtk_test srcwin-2.6 "goto function bar" { + $srcwin goto_func "" bar + set r 0 + + # now get a dump of all tags and check that only one line is + # marked BROWSE_TAG and no lines are STACK_TAG or PC_TAG. + + # We know that list1.c should have BROWSE_TAG set at index 5.2 + # for function "bar". If list1.c is changed or the layout of the source + # window is changed, this must be updated. + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "5.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} { incr r 10} + if {$v == "PC_TAG"} { incr r 100} + } + } + } else { + set r -1 + } + + if {$r == 1} { + # things are OK so far, so just verify the function name is displayed + # in the combobox entry field. + set names [$statbar.func get] + if {[string compare $names "bar"]} {set r -2} + } + set r +} {1} + +# Test: srcwin-2.7 +# Desc: goto function "oof". This tests that the correct line is highlighted +# with BROWSE_TAG and no other lines are highlighted. It also checks that +# the combobox has the correct function name in it. Finally, list1.c +# has an extremely long line, line 32, that breaks some functions. We verify +# that the GDBtk has the correct line number. + +gdbtk_test srcwin-2.7 "goto function oof" { + $srcwin goto_func "" oof + set r 0 + + # now get a dump of all tags and check that only one line is + # marked BROWSE_TAG and no lines are STACK_TAG or PC_TAG. + + # We know that list1.c should have BROWSE_TAG set at index 32.2 + # for function "oof". If list1.c is changed or the layout of the source + # window is changed, this must be updated. + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "32.2"} { + set line_number [$twin get "$i wordstart" "$i wordend"] + if {$line_number == "32"} { + incr r + } else { + incr r -100 + } + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } + } + } else { + set r -1 + } + + if {$r == 1} { + # things are OK so far, so just verify the function name is displayed + # in the combobox entry field. + set names [$statbar.func get] + if {[string compare $names "oof"]} {set r -2} + } + set r +} {1} + +# Test: srcwin-2.8 +# Desc: This test issues a next command while browsing list1.c. +# It should display list0.c and highlight the correct line. +gdbtk_test srcwin-2.8 "step while browsing" { + gdb_immediate "next" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.c"} {set r -1} + if {$func != "main"} {set r -2} + + # check that correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file1(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "11.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-2.9 +# Desc: This test issues a next command while the current +# PC is ready to call a function. It should not go into the function and +# should update the PC highlight correctly. +gdbtk_test srcwin-2.9 "next" { + gdb_immediate "next" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.c"} {set r -1} + if {$func != "main"} {set r -2} + + # check that correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file1(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "12.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-2.10 +# Desc: This test issues a step command while the current +# PC is ready to call a function. It should step into the function. +gdbtk_test srcwin-2.10 "step" { + gdb_immediate "step" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + # check that a new file is displayed + set twin [$stw test_get twin] + set file3(source) [$twin get 1.0 end] + if {![string compare $file1(source) $file3(source)]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-2.11 +# Desc: This test issues a break and a continue +gdbtk_test srcwin-2.11 "set BP and continue" { + gdb_immediate "break oof" 1 + gdb_immediate "continue" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + # we must clear the breakpoint first so it doesn't mess up the + # comparison... + gdb_immediate "clear oof" 1 + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +##### ##### +# # +# SECTION 3: Stack Operations # +# # +##### ##### + +# Test: srcwin-3.1 +# Desc: This tests "stack up" +gdbtk_test srcwin-3.1 "stack up (1)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "long_line"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} { + if {$i == "22.2"} { + incr r + } else { + incr r 10 + } + } + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {2} + +# Test: srcwin-3.2 +# Desc: Another "stack up" test +gdbtk_test srcwin-3.2 "stack up (2)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "bar"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} { + if {$i == "7.2"} { + incr r + } else { + incr r 10 + } + } + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {2} + +# Test: srcwin-3.3 +# Desc: Another "stack up" test +gdbtk_test srcwin-3.3 "stack up (3)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {![string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-3.4 +# Desc: Another "stack up" test +gdbtk_test srcwin-3.4 "stack up (4)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.c"} {set r -1} + if {$func != "main"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file1(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + if {$i == "12.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-3.5 +# Desc: "stack up" when we are at the top +gdbtk_test srcwin-3.5 "stack up when at the top" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.c"} {set r -1} + if {$func != "main"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file1(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + if {$i == "12.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-3.6 +# Desc: "stack down" test +gdbtk_test srcwin-3.6 "stack down" { + $srcwin stack down + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {![string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-3.7 +# Desc: "stack bottom" test +gdbtk_test srcwin-3.7 "stack bottom" { + $srcwin stack bottom + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin-3.8 +# Desc: "stack down" when at bottom +gdbtk_test srcwin-3.8 "stack down when at bottom" { + $srcwin stack down + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# 4 - BREAKPOINTS + +# Test: srcwin-4.1 +# Desc: Set BP in another file. Tests bp and cache functions +gdbtk_test srcwin-4.1 "set BP in another file" { + gdb_immediate "break foo" 1 + $srcwin goto_func "" foo + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + set twin [$stw test_get twin] + + # check for BROWSE_TAG and BP image on correct line + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } elseif {$k == "image"} { + if {$i == "8.0"} { + incr r + } else { + set r -200 + } + } + } + } else { + set r -4 + } + } + + if {$r == 2} { + # clear BP and compare with previous contents. This should succeed, + gdb_immediate "clear foo" 1 + set a [$twin get 1.0 end] + if {[string compare $file3(source) $a]} {set r -3} + } + + set r +} {2} + +# Test: srcwin-4.2 +# Desc: Test temporary BP +gdbtk_test srcwin-4.2 "temporary BP" { + set r 0 + if {[catch {gdb_immediate "tbreak foo" 1} msg]} { + set r -500 + } + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + set twin [$stw test_get twin] + + # check for BROWSE_TAG and BP image on correct line + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } elseif {$k == "image"} { + if {$i == "8.0"} { + incr r + } else { + set r -200 + } + } + } + } else { + set r -4 + } + } + + gdb_immediate "continue" 1 + + # now check for PC_TAG and no image + if {$r == 2} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } elseif {$k == "image"} { + set r -200 + } + } + } else { + set r -4 + } + } + + set r +} {3} + +# Test: srcwin-4.3 +# Desc: Test BP balloons +gdbtk_test srcwin-4.3 "BP Balloons" { + # move pointer out of the way + warp_pointer . 0 0 + set r 0 + gdb_immediate "break 10" 1 + gdb_immediate "tbreak 10" 1 + + set twin [$stw test_get twin] + + # check for BROWSE_TAG and BP image on correct line + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } elseif {$k == "image"} { + if {$i == "10.0"} { + incr r + # we found the bp image, now we will test the bp balloon messages + set balloon [winfo toplevel [namespace tail $srcwin]].__balloon + # shouldn't be mapped yet + if {[winfo ismapped $balloon]} { + set r -3000 + break + } + move_mouse_to $twin [$twin bbox $i] + #wait a second for the balloon message to appear + sleep 1 + if {![winfo ismapped $balloon]} { + set r -4000 + break + } + # read the contents of the balloon and parse it into lines + set a [split [$balloon.label cget -text] \n] + set i 0 + # foreach line parse it and check the type and make sure it is enabled + foreach line $a { + if {[lindex $line 0] == "breakpoint"} {continue} + incr i + set enabled [lindex $line 0] + set bptype [lindex $line 2] + switch $i { + 1 { + if {$bptype != "donttouch"} {set r -1000} + } + 2 { + if {$bptype != "delete"} {set r -2000} + } + } + } + } else { + set r -200 + } + } + } + } else { + set r -4 + } + } + set r +} {2} + +#ManagedWin::open DebugWin + +# Test: srcwin-4.4 +# Desc: Click on line to set BP +gdbtk_test srcwin-4.4 "Click on line to set BP" { + set r 0 + + # click mouse button 1 at index 14.1 + if {![click $twin [$twin bbox 14.1] <Button-1>]} { + set r "Click failed on line 14.1" + } else { + + # now look for BP at line 14 + foreach bpnum [gdb_get_breakpoint_list] { + set bpinfo [gdb_get_breakpoint_info $bpnum] + lassign $bpinfo file func line pc type enabled disposition \ + ignore_count commands cond thread hit_count + set file [lindex [file split $file] end] + if {$file == "list0.h"} { + if {$line == "14"} { + if {$enabled == "1"} {incr r} + if {$func == "foo"} {incr r} + if {$type == "breakpoint"} {incr r} + if {$disposition == "donttouch"} {incr r} + } + } + } + } + set r +} {4} + + +# Test: srcwin-4.5 +# Desc: Continue till here popup +gdbtk_test srcwin-4.5 "Continue till here popup" { + set r + set twin [$stw test_get twin] + + # click mouse button 1 at index 12.1 + set b [$twin bbox 12.1] + if {![click $twin $b <ButtonPress-3>]} { + set r "Click failed on $b" + } else { + + # Hack. Just release the botton 10 pixels to the right and below + # where the press was. This should select the first entry in the + # popup menu, "Continue to Here". This should be made more robust. + if {[llength $b] == 4} { + set x [expr [lindex $b 0] + [lindex $b 2] / 2 + 10] + set y [expr [lindex $b 1] + [lindex $b 3] / 2 + 10] + if {![click $twin [list $x $y 0 0] <ButtonRelease-3>]} { + set r "Click failed at $x $y" + } else { + + # check for PC_TAG on the correct line + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "12.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } elseif {$k == "image"} { + switch $i { + 10.0 {incr r} + 12.0 {incr r} + 14.0 {incr r} + default {incr r 1000} + } + } + } + } else { + set r -4 + } + } + } + } else { + set r "Line 12.1 was not visible..." + } + # should have seen on PC_TAG at line 12, plus BP images at 10.0, 12.0 and 14.0 + } + set r +} {4} + +# 5.1 balloon variables +# Test: srcwin-5.1 +# Desc: variable balloon test +# continues to BP at line 14 and checks to see that value was updated +gdbtk_test srcwin-5.1 "variable balloon test" { + # move pointer out of the way + warp_pointer . 0 0 + set r 0 + set twin [$stw test_get twin] + + # move pointer to variable "x" and check balloon + set index [string first "x++" [$twin get 10.0 10.end]] + move_mouse_to $twin [$twin bbox 10.$index] + sleep 1 + if {[winfo ismapped $balloon]} { + if {![string compare "x=6" [$balloon.label cget -text]]} {incr r} + gdb_immediate "continue" 1 + if {![string compare "x=8" [$balloon.label cget -text]]} {incr r} + } else { + set r -1 + } + + set r +} {2} + +# 6.1 mixed mode disassembly of include file +# Test: srcwin-6.1 +# Desc: Some versions of GDBtk can't do mixed-mode disassembly of a function +# that is in an include file. +gdbtk_test srcwin-6.1 "mixed mode disassembly of include file" { + set r 0 + $srcwin mode "" MIXED + + # check contents of name and function comboboxes + set name [$statbar.name get] + set func [$statbar.func get] + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + # check contents of source window + set twin [$stw test_get twin] + set text [$twin get 1.0 end] + # Is it correct? I don't know. Guess we look for some pieces of source... + if {[string first "static void" $text] != -1 && + [string first "foo (x)" $text] != -1 && + [string first "bar (x++);" $text] != -1} { + set r 1 + } + + set r +} {1} + +gdbtk_test_done + +# Local variables: +# mode: tcl +# change-log-default-name: "ChangeLog-gdbtk" +# End: diff --git a/gdb/testsuite/gdb.gdbtk/srcwin2.test b/gdb/testsuite/gdb.gdbtk/srcwin2.test new file mode 100644 index 00000000000..395ce0b3138 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/srcwin2.test @@ -0,0 +1,906 @@ +# Copyright (C) 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Martin Hunt (hunt@cygnus.com) + + +# same as srcwin.test, except test debugging executables +# when source files are missing. + +# Read in the standard defs file + +if {![gdbtk_read_defs]} { + break +} + +global objdir srcdir + +##### ##### +# # +# SECTION 1: Mode Tests # +# # +##### ##### + +# Load the test executable +if {$tcl_platform(platform) == "windows"} { + set file [file join $objdir list.exe] +} else { + set file [file join $objdir list] +} + +# This isn't a test case, since if this fails, we're hosed. +if {[catch {gdb_cmd "file $file" 1} t]} { + # an error occured loading the file + gdbtk_test_error "loading \"$file\": $t" +} + +set srcwin [ManagedWin::open SrcWin] +set stw [$srcwin test_get twin] +set twin [$stw test_get twin] +set statbar [$srcwin test_get _statbar] + +# get things started +gdb_cmd "break main" +run_executable + +# Test: srcwin2-1.1 +# Desc: Check for something in source window +gdbtk_test srcwin2-1.1 "source window has contents" { + set r 0 + set file1(source) [$twin get 1.0 end] + if {$file1(source) == ""} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.2 +# Desc: source->assembly mode change +gdbtk_test srcwin2-1.2 "source->assembly mode change" { + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + set file1(assembly) [$twin get 1.0 end] + # source == assembly because for there is no source + string compare $file1(source) $file1(assembly) +} {0} + +# Test: srcwin2-1.3 +# Desc: assembly->mixed mode change +gdbtk_test srcwin2-1.3 "assembly->mixed mode change" { + set r 0 + $srcwin mode "" MIXED + set twin [$stw test_get twin] + set file1(mixed) [$twin get 1.0 end] + # mixed != assembly because the lines with source should + # be noted, even if source in unavailable. + if {$file1(mixed) == $file1(assembly)} {set r -1} + if {[$statbar.mode get] != "MIXED"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.4 +# Desc: mixed->src+asm mode change +gdbtk_test srcwin2-1.4 "mixed->src+asm mode change" { + set r 0 + # mode change may fail if fallover to ASSEMBLY fails + if {[catch {$srcwin mode "" SRC+ASM}]} { set r -5 } + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $file1(assembly)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.5 +# Desc: src+asm->source mode change +gdbtk_test srcwin2-1.5 "src+asm->source mode change" { + set r 0 + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + if {[$stw test_get bwin] != ""} {set r -2} + if {[$twin get 1.0 end] != $file1(assembly)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -3} + set r +} {0} + +# Test: srcwin2-1.6 +# Desc: source->mixed mode change +gdbtk_test srcwin2-1.6 "source->mixed mode change" { + set r 0 + $srcwin mode "" MIXED + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $file1(mixed)} {set r -1} + if {[$statbar.mode get] != "MIXED"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.7 +# Desc: mixed->source mode change +gdbtk_test srcwin2-1.7 "mixed->source mode change" { + set r 0 + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $file1(source)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.8 +# Desc: source->src+asm mode change +gdbtk_test srcwin2-1.8 "source->src+asm mode change" { + set r 0 + # mode change may fail if fallover to ASSEMBLY fails + if {[catch {$srcwin mode "" SRC+ASM}]} { set r -5 } + set twin [$stw test_get twin] + set bwin [$stw test_get bwin] + if {[$twin get 1.0 end] != $file1(assembly)} {set r -1} + if {$bwin != ""} {set r -2} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -3} + set r +} {0} + +# Test: srcwin2-1.9 +# Desc: src+asm->assembly mode change +gdbtk_test srcwin2-1.9 "src+asm->assembly mode change" { + set r 0 + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $file1(assembly)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.10 +# Desc: assembly->src+asm mode change +gdbtk_test srcwin2-1.10 "assembly->src+asm mode change" { + set r 0 + # mode change may fail if fallover to ASSEMBLY fails + if {[catch {$srcwin mode "" SRC+ASM}]} { set r -5 } + set twin [$stw test_get twin] + set bwin [$stw test_get bwin] + if {[$twin get 1.0 end] != $file1(assembly)} {set r -1} + if {$bwin != ""} {set r -2} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -3} + set r +} {0} + +# Test: srcwin2-1.11 +# Desc: src+asm->mixed mode change +gdbtk_test srcwin2-1.11 "src+asm->mixed mode change" { + set r 0 + $srcwin mode "" MIXED + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $file1(mixed)} {set r -1} + if {[$statbar.mode get] != "MIXED"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.12 +# Desc: mixed->assembly mode change +gdbtk_test srcwin2-1.12 "mixed->assembly mode change" { + set r 0 + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $file1(assembly)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin2-1.13 +# Desc: assembly->source mode change +gdbtk_test srcwin2-1.13 "assembly->source mode change" { + set r 0 + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $file1(source)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + + +##### ##### +# # +# SECTION 2: Basic Operations # +# # +##### ##### + +# Test: srcwin2-2.1 +# Desc: check contents of filename combobox +gdbtk_test srcwin2-2.1 "check contents of filename combobox" { + set names [$statbar.name listget 0 end] + set r 0 + foreach f {list0.c list1.c list0.h} { + if {[lsearch $names $f] != -1} { + incr r + } + } + set r +} {3} + +# Test: srcwin2-2.2 +# Desc: check contents of function combobox +gdbtk_test srcwin2-2.2 "check contents of function combobox" { + set names [$statbar.func listget 0 end] + set r 0 + foreach f {main foo unused} { + if {[lsearch $names $f] != -1} { + incr r + } + } + set r +} {3} + +# Test: srcwin2-2.3 +# Desc: goto filename +gdbtk_test srcwin2-2.3 "goto filename" { + set func [$srcwin test_get _name 1] + $func "" list1.c + set twin [$stw test_get twin] + set file2(source) [$twin get 1.0 end] + expr {![string compare $file1(source) $file2(source)]} +} {0} + +# Test: srcwin2-2.4 +# Desc: check contents of function combobox +gdbtk_test srcwin2-2.4 "check contents of function combobox" { + set names [$statbar.func listget 0 end] + set r 0 + foreach f {bar long_line oof unused} { + if {[lsearch $names $f] != -1} { + incr r + } + } + set r +} {4} + +# Test: srcwin2-2.5 +# Desc: function combobox entry field should be empty after switching to a new file +gdbtk_test srcwin2-2.5 "function combobox entry field should be empty" { + set names [$statbar.func get] + string length $names +} {0} + +# Test: srcwin2-2.6 +# Desc: goto function +gdbtk_test srcwin2-2.6 "goto function bar" { + $srcwin goto_func "" bar + set r 0 + + # now get a dump of all tags and check that only one line is + # marked BROWSE_TAG and no lines are STACK_TAG or PC_TAG. + + # We know that list1.c should have BROWSE_TAG set at index 5.2 + # for function "bar". If list1.c is changed or the layout of the source + # window is changed, this must be updated. + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "5.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} { incr r 10} + if {$v == "PC_TAG"} { incr r 100} + } + } + } else { + set r -1 + } + + if {$r == 1} { + # things are OK so far, so just verify the function name is displayed + # in the combobox entry field. + set names [$statbar.func get] + if {[string compare $names "bar"]} {set r -2} + } + set r +} {1} + +# Test: srcwin2-2.7 +# Desc: goto function "oof". This tests that the correct line is highlighted +# with BROWSE_TAG and no other lines are highlighted. It also checks that +# the combobox has the correct function name in it. Finally, list1.c +# has an extremely long line, line 32, that breaks some functions. We verify +# that the GDBtk has the correct line number. + +gdbtk_test srcwin2-2.7 "goto function oof" { + $srcwin goto_func "" oof + set r 0 + + # now get a dump of all tags and check that only one line is + # marked BROWSE_TAG and no lines are STACK_TAG or PC_TAG. + + # We know that list1.c should have BROWSE_TAG set at index 32.2 + # for function "oof". If list1.c is changed or the layout of the source + # window is changed, this must be updated. + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "32.2"} { + set line_number [$twin get "$i wordstart" "$i wordend"] + if {$line_number == "32"} { + incr r + } else { + incr r -100 + } + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } + } + } else { + set r -1 + } + + if {$r == 1} { + # things are OK so far, so just verify the function name is displayed + # in the combobox entry field. + set names [$statbar.func get] + if {[string compare $names "oof"]} {set r -2} + } + set r +} {1} + +# Test: srcwin2-2.8 +# Desc: This test issues a next command while browsing list1.c. +# It should display list0.c and highlight the correct line. +gdbtk_test srcwin2-2.8 "step while browsing" { + gdb_immediate "next" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.c"} {set r -1} + if {$func != "main"} {set r -2} + + # check that correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file1(source) $a]} {set r -3} + + # check for PC_TAG + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin2-2.11 +# Desc: This test issues a break and a continue +gdbtk_test srcwin2-2.11 "set BP and continue" { + gdb_immediate "break oof" 1 + gdb_immediate "continue" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + # we must clear the breakpoint first so it doesn't mess up the + # comparison... + gdb_immediate "clear oof" 1 + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +##### ##### +# # +# SECTION 3: Stack Operations # +# # +##### ##### + +# Test: srcwin2-3.1 +# Desc: This tests "stack up" +gdbtk_test srcwin2-3.1 "stack up (1)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "long_line"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} { + if {$i == "22.2"} { + incr r + } else { + incr r 10 + } + } + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {2} + +# Test: srcwin2-3.2 +# Desc: Another "stack up" test +gdbtk_test srcwin2-3.2 "stack up (2)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "bar"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} { + if {$i == "7.2"} { + incr r + } else { + incr r 10 + } + } + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {2} + +# Test: srcwin2-3.3 +# Desc: Another "stack up" test +gdbtk_test srcwin2-3.3 "stack up (3)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set file3(source) [$twin get 1.0 end] + if {![string compare $file2(source) $file3(source)]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin2-3.4 +# Desc: Another "stack up" test +gdbtk_test srcwin2-3.4 "stack up (4)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.c"} {set r -1} + if {$func != "main"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file1(source) $a]} {set r -3} + + # check for STACK_TAG + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + incr r + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin2-3.5 +# Desc: "stack up" when we are at the top +gdbtk_test srcwin2-3.5 "stack up when at the top" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.c"} {set r -1} + if {$func != "main"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file1(source) $a]} {set r -3} + + # check for STACK_TAG + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + incr r + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin2-3.6 +# Desc: "stack down" test +gdbtk_test srcwin2-3.6 "stack down" { + $srcwin stack down + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {![string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin2-3.7 +# Desc: "stack bottom" test +gdbtk_test srcwin2-3.7 "stack bottom" { + $srcwin stack bottom + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin2-3.8 +# Desc: "stack down" when at bottom +gdbtk_test srcwin2-3.8 "stack down when at bottom" { + $srcwin stack down + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list1.c"} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $file2(source) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "32.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# 4.1 bp, multiple, balloon, etc + +# Test: srcwin2-4.1 +# Desc: Set BP in another file. Tests bp and cache functions +gdbtk_test srcwin2-4.1 "set BP in another file" { + gdb_immediate "break foo" 1 + $srcwin goto_func "" foo + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + set twin [$stw test_get twin] + + # check for BROWSE_TAG and BP image on correct line + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } elseif {$k == "image"} { + if {$i == "8.0"} { + incr r + } else { + set r -200 + } + } + } + } else { + set r -4 + } + } + + if {$r == 2} { + # clear BP and compare with previous contents. This should succeed, + gdb_immediate "clear foo" 1 + set a [$twin get 1.0 end] + if {[string compare $file3(source) $a]} {set r -3} + } + + set r +} {2} + +# Test: srcwin2-4.2 +# Desc: Test temporary BP +gdbtk_test srcwin2-4.2 "temporary BP" { + set r 0 + if {[catch {gdb_immediate "tbreak foo" 1} msg]} { + set r -500 + } + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != "list0.h"} {set r -1} + if {$func != "foo"} {set r -2} + + set twin [$stw test_get twin] + + # check for BROWSE_TAG and BP image on correct line + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } elseif {$k == "image"} { + if {$i == "8.0"} { + incr r + } else { + set r -200 + } + } + } + } else { + set r -4 + } + } + + gdb_immediate "continue" 1 + + # now check for PC_TAG and no image + if {$r == 2} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + if {$i == "8.2"} { + incr r + } else { + incr r 5 + } + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } elseif {$k == "image"} { + set r -200 + } + } + } else { + set r -4 + } + } + + set r +} {3} + +gdbtk_test_done + +# Local variables: +# mode: tcl +# change-log-default-name: "ChangeLog-gdbtk" +# End: diff --git a/gdb/testsuite/gdb.gdbtk/srcwin3.test b/gdb/testsuite/gdb.gdbtk/srcwin3.test new file mode 100644 index 00000000000..c329e9ca096 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/srcwin3.test @@ -0,0 +1,798 @@ +# Copyright (C) 1999 Cygnus Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Martin Hunt (hunt@cygnus.com) + +########################################################### +# same as srcwin.test, except test debugging executables # +# build without "-g" # +########################################################### + +# Read in the standard defs file + +if {![gdbtk_read_defs]} { + break +} + +global objdir srcdir + +##### ##### +# # +# SECTION 1: Mode Tests # +# # +##### ##### + +# Load the test executable +if {$tcl_platform(platform) == "windows"} { + set file [file join $objdir list.exe] +} else { + set file [file join $objdir list] +} + +# This isn't a test case, since if this fails, we're hosed. +if {[catch {gdb_cmd "file $file" 1} t]} { + # an error occured loading the file + gdbtk_test_error "loading \"$file\": $t" +} + +set srcwin [ManagedWin::open SrcWin] +set stw [$srcwin test_get twin] +set twin [$stw test_get twin] +set statbar [$srcwin test_get _statbar] + +# get things started +gdb_cmd "break main" +run_executable + +# Test: srcwin3-1.1 +# Desc: Check for something in source window +gdbtk_test srcwin3-1.1 "source window has contents" { + set r 0 + set source(main) [$twin get 1.0 end] + if {$source(main) == ""} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.2 +# Desc: source->assembly mode change +gdbtk_test srcwin3-1.2 "source->assembly mode change" { + set r 0 + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + if {$source(main) != [$twin get 1.0 end]} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.3 +# Desc: assembly->mixed mode change +gdbtk_test srcwin3-1.3 "assembly->mixed mode change" { + set r 0 + $srcwin mode "" MIXED + set twin [$stw test_get twin] + if {$source(main) != [$twin get 1.0 end]} {set r -1} + if {[$statbar.mode get] != "MIXED"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.4 +# Desc: mixed->src+asm mode change +gdbtk_test srcwin3-1.4 "mixed->src+asm mode change" { + set r 0 + # mode change may fail if fallover to ASSEMBLY fails + if {[catch {$srcwin mode "" SRC+ASM}]} { set r -5 } + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.5 +# Desc: src+asm->source mode change +gdbtk_test srcwin3-1.5 "src+asm->source mode change" { + set r 0 + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + if {[$stw test_get bwin] != ""} {set r -2} + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -3} + set r +} {0} + +# Test: srcwin3-1.6 +# Desc: source->mixed mode change +gdbtk_test srcwin3-1.6 "source->mixed mode change" { + set r 0 + $srcwin mode "" MIXED + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "MIXED"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.7 +# Desc: mixed->source mode change +gdbtk_test srcwin3-1.7 "mixed->source mode change" { + set r 0 + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.8 +# Desc: source->src+asm mode change +gdbtk_test srcwin3-1.8 "source->src+asm mode change" { + set r 0 + # mode change may fail if fallover to ASSEMBLY fails + if {[catch {$srcwin mode "" SRC+ASM}]} { set r -5 } + set twin [$stw test_get twin] + set bwin [$stw test_get bwin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {$bwin != ""} {set r -2} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -3} + set r +} {0} + +# Test: srcwin3-1.9 +# Desc: src+asm->assembly mode change +gdbtk_test srcwin3-1.9 "src+asm->assembly mode change" { + set r 0 + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.10 +# Desc: assembly->src+asm mode change +gdbtk_test srcwin3-1.10 "assembly->src+asm mode change" { + set r 0 + # mode change may fail if fallover to ASSEMBLY fails + if {[catch {$srcwin mode "" SRC+ASM}]} { set r -5 } + set twin [$stw test_get twin] + set bwin [$stw test_get bwin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {$bwin != ""} {set r -2} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -3} + set r +} {0} + +# Test: srcwin3-1.11 +# Desc: src+asm->mixed mode change +gdbtk_test srcwin3-1.11 "src+asm->mixed mode change" { + set r 0 + $srcwin mode "" MIXED + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "MIXED"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.12 +# Desc: mixed->assembly mode change +gdbtk_test srcwin3-1.12 "mixed->assembly mode change" { + set r 0 + $srcwin mode "" ASSEMBLY + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + +# Test: srcwin3-1.13 +# Desc: assembly->source mode change +gdbtk_test srcwin3-1.13 "assembly->source mode change" { + set r 0 + $srcwin mode "" SOURCE + set twin [$stw test_get twin] + if {[$twin get 1.0 end] != $source(main)} {set r -1} + if {[$statbar.mode get] != "ASSEMBLY"} {set r -2} + set r +} {0} + + +##### ##### +# # +# SECTION 2: Basic Operations # +# # +##### ##### + +# Test: srcwin3-2.2 +# Desc: check contents of function combobox +# There won't be any because we have no debug info +gdbtk_test srcwin3-2.2 "check contents of function combobox" { + set names [$statbar.func listget 0 end] + llength $names +} {0} + +# Test: srcwin3-2.3 +# Desc: goto filename - this won't work, but should leave things as they were +gdbtk_test srcwin3-2.3 "goto filename" { + set func [$srcwin test_get _name 1] + $func "" list1.c + set twin [$stw test_get twin] + string compare $source(main) [$twin get 1.0 end] +} {0} + +# Test: srcwin3-2.6 +# Desc: goto function +gdbtk_test srcwin3-2.6 "goto function bar" { + $srcwin goto_func "" bar + set r 0 + set twin [$stw test_get twin] + set source(bar) [$twin get 1.0 end] + + if {$source(bar) == $source(main)} {set r -1000} + + # now get a dump of all tags and check that only one line is + # marked BROWSE_TAG and no lines are STACK_TAG or PC_TAG. + + # We know that list1.c should have BROWSE_TAG set at index 5.2 + # for function "bar". If list1.c is changed or the layout of the source + # window is changed, this must be updated. + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + incr r + } + if {$v == "STACK_TAG"} { incr r 10} + if {$v == "PC_TAG"} { incr r 100} + } + } + } else { + set r -1 + } + + if {$r == 1} { + # things are OK so far, so just verify the function name is displayed + # in the combobox entry field. + set names [$statbar.func get] + if {[string compare $names "bar"]} {set r -2} + } + set r +} {1} + +# Test: srcwin3-2.7 +# Desc: goto function "oof". This tests that the correct line is highlighted +# with BROWSE_TAG and no other lines are highlighted. It also checks that +# the combobox has the correct function name in it. + +gdbtk_test srcwin3-2.7 "goto function oof" { + $srcwin goto_func "" oof + set r 0 + + set twin [$stw test_get twin] + set source(oof) [$twin get 1.0 end] + + if {$source(bar) == $source(oof)} {set r -1000} + if {$source(oof) == $source(main)} {set r -2000} + + # now get a dump of all tags and check that only one line is + # marked BROWSE_TAG and no lines are STACK_TAG or PC_TAG. + + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } + } + } else { + set r -1 + } + + if {$r == 1} { + # things are OK so far, so just verify the function name is displayed + # in the combobox entry field. + set names [$statbar.func get] + if {[string compare $names "oof"]} {set r -2} + } + set r +} {1} + +# Test: srcwin3-2.8 +# Desc: This test issues a nexti command while browsing oof. +# It should jump back to main +gdbtk_test srcwin3-2.8 "nexti while browsing" { + gdb_immediate "nexti" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of function combobox + if {$func != "main"} {set r -2} + if {$name != ""} {set r -1} + + # check that correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(main) $a]} {set r -3} + + # check for PC_TAG + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-2.11 +# Desc: This test issues a break and a continue +gdbtk_test srcwin3-2.11 "set BP and continue" { + gdb_immediate "break oof" 1 + gdb_immediate "continue" 1 + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + # we must clear the breakpoint first so it doesn't mess up the + # comparison... + gdb_immediate "clear oof" 1 + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(oof) $a]} {set r -3} + + # check for PC_TAG + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +##### ##### +# # +# SECTION 3: Stack Operations # +# # +##### ##### + +# Test: srcwin3-3.1 +# Desc: This tests "stack up" +gdbtk_test srcwin3-3.1 "stack up (1)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "long_line"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set source(long_line) [$twin get 1.0 end] + if {![string compare $source(long_line) $source(oof)]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} {incr r 5} + if {$v == "STACK_TAG"} {incr r} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-3.2 +# Desc: Another "stack up" test +gdbtk_test srcwin3-3.2 "stack up (2)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "bar"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(bar) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + set r -100 + } + if {$v == "STACK_TAG"} { + incr r + } + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-3.3 +# Desc: Another "stack up" test +gdbtk_test srcwin3-3.3 "stack up (3)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "foo"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set source(foo) [$twin get 1.0 end] + if {![string compare $source(foo) $source(bar)]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + incr r + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-3.4 +# Desc: Another "stack up" test +gdbtk_test srcwin3-3.4 "stack up (4)" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "main"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(main) $a]} {set r -3} + + # check for STACK_TAG + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + incr r + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-3.5 +# Desc: "stack up" when we are at the top +gdbtk_test srcwin3-3.5 "stack up when at the top" { + $srcwin stack up + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "main"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(main) $a]} {set r -3} + + # check for STACK_TAG + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + incr r + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-3.6 +# Desc: "stack down" test +gdbtk_test srcwin3-3.6 "stack down" { + $srcwin stack down + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "foo"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(foo) $a]} {set r -3} + + # check for PC_TAG and STACK_TAG on correct lines + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "STACK_TAG"} { + incr r + } + if {$v == "PC_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-3.7 +# Desc: "stack bottom" test +gdbtk_test srcwin3-3.7 "stack bottom" { + $srcwin stack bottom + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(oof) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# Test: srcwin3-3.8 +# Desc: "stack down" when at bottom +gdbtk_test srcwin3-3.8 "stack down when at bottom" { + $srcwin stack down + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "oof"} {set r -2} + + # check that the correct file is displayed + set twin [$stw test_get twin] + set a [$twin get 1.0 end] + if {[string compare $source(oof) $a]} {set r -3} + + # check for PC_TAG on correct line + if {$r == 0} { + if {![catch {set z [$twin dump -tag 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } + } + } else { + set r -4 + } + } + set r +} {1} + +# 4.1 bp, multiple, balloon, etc + +# Test: srcwin3-4.1 +# Desc: Set BP in another file. Tests bp and cache functions +gdbtk_test srcwin3-4.1 "set BP in another file" { + gdb_immediate "break foo" 1 + $srcwin goto_func "" foo + set r 0 + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "foo"} {set r -2} + + set twin [$stw test_get twin] + + # check for BROWSE_TAG and BP image + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } elseif {$k == "image"} { + incr r + } + } + } else { + set r -4 + } + } + + if {$r == 2} { + # clear BP and compare with previous contents. This should succeed, + gdb_immediate "clear foo" 1 + set a [$twin get 1.0 end] + if {[string compare $source(foo) $a]} {set r -3} + } + + set r +} {2} + +# Test: srcwin3-4.2 +# Desc: Test temporary BP +gdbtk_test srcwin3-4.2 "temporary BP" { + set r 0 + if {[catch {gdb_immediate "tbreak foo" 1} msg]} { + set r -500 + } + set name [$statbar.name get] + set func [$statbar.func get] + + # check contents of name and function comboboxes + if {$name != ""} {set r -1} + if {$func != "foo"} {set r -2} + + set twin [$stw test_get twin] + + # check for BROWSE_TAG and BP image on correct line + if {$r == 0} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "BROWSE_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "PC_TAG"} {incr r 100} + } elseif {$k == "image"} { + incr r + } + } + } else { + set r -4 + } + } + + gdb_immediate "continue" 1 + + # now check for PC_TAG and no image + if {$r == 2} { + if {![catch {set z [$twin dump 1.0 end]}]} { + foreach {k v i} $z { + if {$k == "tagon"} { + if {$v == "PC_TAG"} { + incr r + } + if {$v == "STACK_TAG"} {incr r 10} + if {$v == "BROWSE_TAG"} {incr r 100} + } elseif {$k == "image"} { + set r -200 + } + } + } else { + set r -4 + } + } + + set r +} {3} + +gdbtk_test_done + +# Local variables: +# mode: tcl +# change-log-default-name: "ChangeLog-gdbtk" +# End: diff --git a/gdb/testsuite/gdb.gdbtk/stack1.c b/gdb/testsuite/gdb.gdbtk/stack1.c new file mode 100644 index 00000000000..389260a22a5 --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/stack1.c @@ -0,0 +1,231 @@ +/* Functions defined in other files */ +extern void extern_func1_1 (int a, char *b, unsigned long c); + +/* Functions defined in this file */ +static void static_func_1 (int a, char *b, unsigned long c); +static void static_func_2 (int a, char *b, unsigned long c); +static void static_func_3 (int a, char *b, unsigned long c); +static void static_func_4 (int a, char *b, unsigned long c); +static void static_func_5 (int a, char *b, unsigned long c); +static void static_func_6 (int a, char *b, unsigned long c); +static void static_func_7 (int a, char *b, unsigned long c); +static void static_func_8 (int a, char *b, unsigned long c); +static void static_func_9 (int a, char *b, unsigned long c); +static void static_func_10 (int a, char *b, unsigned long c); +static void static_func_11 (int a, char *b, unsigned long c); +static void static_func_12 (int a, char *b, unsigned long c); +static void static_func_13 (int a, char *b, unsigned long c); +static void static_func_14 (int a, char *b, unsigned long c); +static void static_func_15 (int a, char *b, unsigned long c); + +void func_1 (int a, char *b, unsigned long c); +void func_2 (int a, char *b, unsigned long c); +void func_3 (int a, char *b, unsigned long c); +void func_4 (int a, char *b, unsigned long c); +void func_5 (int a, char *b, unsigned long c); +void func_6 (int a, char *b, unsigned long c); +void func_7 (int a, char *b, unsigned long c); +void func_8 (int a, char *b, unsigned long c); +void func_9 (int a, char *b, unsigned long c); +void func_10 (int a, char *b, unsigned long c); +void func_11 (int a, char *b, unsigned long c); +void func_12 (int a, char *b, unsigned long c); +void func_13 (int a, char *b, unsigned long c); +void func_14 (int a, char *b, unsigned long c); +void func_15 (int a, char *b, unsigned long c); + +int +main (int argc, char *argv[]) +{ + int a; + char *b; + unsigned long c; + + a = 1; + b = "This is a string."; + c = 0xdeadL; + + func_1 (a, b, c); + + exit (0); +} + +void +func_1 (int a, char *b, unsigned long c) +{ + func_2 (a, b, c); +} + +void +func_2 (int a, char *b, unsigned long c) +{ + func_3 (a, b, c); +} + +void +func_3 (int a, char *b, unsigned long c) +{ + func_4 (a, b, c); +} + +void +func_4 (int a, char *b, unsigned long c) +{ + func_5 (a, b, c); +} + +void +func_5 (int a, char *b, unsigned long c) +{ + func_6 (a, b, c); +} + +void +func_6 (int a, char *b, unsigned long c) +{ + func_7 (a, b, c); +} + +void +func_7 (int a, char *b, unsigned long c) +{ + func_8 (a, b, c); +} + +void +func_8 (int a, char *b, unsigned long c) +{ + func_9 (a, b, c); +} + +void +func_9 (int a, char *b, unsigned long c) +{ + func_10 (a, b, c); +} + +void +func_10 (int a, char *b, unsigned long c) +{ + func_11 (a, b, c); +} + +void +func_11 (int a, char *b, unsigned long c) +{ + func_12 (a, b, c); +} + +void +func_12 (int a, char *b, unsigned long c) +{ + func_13 (a, b, c); +} + +void +func_13 (int a, char *b, unsigned long c) +{ + func_14 (a, b, c); +} + +void +func_14 (int a, char *b, unsigned long c) +{ + func_15 (a, b, c); +} + +void +func_15 (int a, char *b, unsigned long c) +{ + static_func_1 (a, b, c); +} + +static void +static_func_1 (int a, char *b, unsigned long c) +{ + static_func_2 (a, b, c); +} + +static void +static_func_2 (int a, char *b, unsigned long c) +{ + static_func_3 (a, b, c); +} + +static void +static_func_3 (int a, char *b, unsigned long c) +{ + static_func_4 (a, b, c); +} + +static void +static_func_4 (int a, char *b, unsigned long c) +{ + static_func_5 (a, b, c); +} + +static void +static_func_5 (int a, char *b, unsigned long c) +{ + static_func_6 (a, b, c); +} + +static void +static_func_6 (int a, char *b, unsigned long c) +{ + static_func_7 (a, b, c); +} + +static void +static_func_7 (int a, char *b, unsigned long c) +{ + static_func_8 (a, b, c); +} + +static void +static_func_8 (int a, char *b, unsigned long c) +{ + static_func_9 (a, b, c); +} + +static void +static_func_9 (int a, char *b, unsigned long c) +{ + static_func_10 (a, b, c); +} + +static void +static_func_10 (int a, char *b, unsigned long c) +{ + static_func_11 (a, b, c); +} + +static void +static_func_11 (int a, char *b, unsigned long c) +{ + static_func_12 (a, b, c); +} + +static void +static_func_12 (int a, char *b, unsigned long c) +{ + static_func_13 (a, b, c); +} + +static void +static_func_13 (int a, char *b, unsigned long c) +{ + static_func_14 (a, b, c); +} + +static void +static_func_14 (int a, char *b, unsigned long c) +{ + static_func_15 (a, b, c); +} + +static void +static_func_15 (int a, char *b, unsigned long c) +{ + extern_func1_1 (a, b, c); +} diff --git a/gdb/testsuite/gdb.gdbtk/stack2.c b/gdb/testsuite/gdb.gdbtk/stack2.c new file mode 100644 index 00000000000..db47c469e6e --- /dev/null +++ b/gdb/testsuite/gdb.gdbtk/stack2.c @@ -0,0 +1,107 @@ +/* Functions defined in this file */ +void extern_func1_1 (int, char *, unsigned long); +void extern_func1_2 (int, char *, unsigned long); +void extern_func1_3 (int, char *, unsigned long); +void extern_func1_4 (int, char *, unsigned long); +void extern_func1_5 (int, char *, unsigned long); +void extern_func1_6 (int, char *, unsigned long); +void extern_func1_7 (int, char *, unsigned long); +void extern_func1_8 (int, char *, unsigned long); +void extern_func1_9 (int, char *, unsigned long); +void extern_func1_10 (int, char *, unsigned long); +void extern_func1_11 (int, char *, unsigned long); +void extern_func1_12 (int, char *, unsigned long); +void extern_func1_13 (int, char *, unsigned long); +void extern_func1_14 (int, char *, unsigned long); +void extern_func1_15 (int, char *, unsigned long); + +void +extern_func1_1 (int a, char *b, unsigned long c) +{ + extern_func1_2 (a, b, c); +} + +void +extern_func1_2 (int a, char *b, unsigned long c) +{ + extern_func1_3 (a, b, c); +} + +void +extern_func1_3 (int a, char *b, unsigned long c) +{ + extern_func1_4 (a, b, c); +} + +void +extern_func1_4 (int a, char *b, unsigned long c) +{ + extern_func1_5 (a, b, c); +} + +void +extern_func1_5 (int a, char *b, unsigned long c) +{ + extern_func1_6 (a, b, c); +} + +void +extern_func1_6 (int a, char *b, unsigned long c) +{ + extern_func1_7 (a, b, c); +} + +void +extern_func1_7 (int a, char *b, unsigned long c) +{ + extern_func1_8 (a, b, c); +} + +void +extern_func1_8 (int a, char *b, unsigned long c) +{ + extern_func1_9 (a, b, c); +} + +void +extern_func1_9 (int a, char *b, unsigned long c) +{ + extern_func1_10 (a, b, c); +} + +void +extern_func1_10 (int a, char *b, unsigned long c) +{ + extern_func1_11 (a, b, c); +} + +void +extern_func1_11 (int a, char *b, unsigned long c) +{ + extern_func1_12 (a, b, c); +} + +void +extern_func1_12 (int a, char *b, unsigned long c) +{ + extern_func1_13 (a, b, c); +} + +void +extern_func1_13 (int a, char *b, unsigned long c) +{ + extern_func1_14 (a, b, c); +} + +void +extern_func1_14 (int a, char *b, unsigned long c) +{ + extern_func1_15 (a, b, c); +} + +void +extern_func1_15 (int a, char *b, unsigned long c) +{ + /* THE END */ + return; +} |