Branch: refs/heads/master Author: Dimitar Zhekov dimitar.zhekov@gmail.com Committer: Dimitar Zhekov dimitar.zhekov@gmail.com Date: Mon, 06 Jan 2014 18:50:59 UTC Commit: 601b1cf5c611aaad0bfb8210396a3991e03c8f78 https://github.com/geany/geany-plugins/commit/601b1cf5c611aaad0bfb8210396a39...
Log Message: ----------- breakpoint improvements and other changes, version 0.93.1
Modified Paths: -------------- scope/ChangeLog scope/NEWS scope/data/scope.glade scope/docs/codes.html scope/docs/scope.html scope/src/break.c scope/src/debug.c scope/src/gtk216.c scope/src/inspect.c scope/src/scope.c scope/src/watch.c
Modified: scope/ChangeLog 33 files changed, 30 insertions(+), 3 deletions(-) =================================================================== @@ -1,9 +1,36 @@ +2013-01-06 Dimitar Zhekov dimitar.zhekov@gmail.com + + * data/scope.glade, src/break.c: + Show breakpoint origin in the type column, with tooltip. + * data/scope.glade, docs/scope.html: + "Temporary breakpoint at" -> "Temporary breakpoint on load at". + * docs/scope.html: + Some improvements and clarifications. + * src/break.c: + Remove the "Temporary breakpoint on load" only on unload, not on + hit or when resetting the program state. + Show catchpoint condition (depends on the gdb version). + * src/break.c, src/debug.c, src/inspect.c: + Apply any unapplied breakpoints/inspects marked as "Apply on run" + on each run (only important if "Auto run/exit" is off). + * src/gtk216.c: + Make sort_column_ids[] const. + * src/scope.c, src/watch.c: + Unify GPOINTER_TO_INT(FALSE) handling. + * src/scope.c: + Emit a message to Geany log if scope.glade can't be loaded, by + Enrico Tröger. + Removed static last_statusbar_state, unused since ScpTreeStore + dynamic registration. + * docs/scope.html, src/scope.c: + Increased version to 0.93.1. + 2013-10-26 Dimitar Zhekov dimitar.zhekov@gmail.com
* src/memory.c: - Handle offset (albeit it seems that gdb just adds it to start). - Fix count for memory block with holes. - Use g_ascii_strtoull() instead of sscanf. + Handle offset (although it seems that gdb just adds it to start). + Fix counting for memory block with holes. + sscanf() -> g_ascii_strtoull(). * src/prefs.c: Removed an unused structure.
Modified: scope/NEWS 10 files changed, 10 insertions(+), 0 deletions(-) =================================================================== @@ -1,3 +1,13 @@ +Scope 0.93.1 (2014-01-06): + + * Show breakpoint origin in the type column, with tooltip. + + * Show catchpoint condition (depends on the gdb version). + + * Apply any unapplied breakpoints/inspects marked as "Apply on + run" on each run (only important if "Auto run/exit" is off). + + Scope 0.92 (2013-09-07)
* Better support for Geany message window on right, but don't
Modified: scope/data/scope.glade 4 files changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -1416,7 +1416,7 @@ <!-- column-name break_store_temporary --> <column type="gboolean"/> <!-- column-name break_store_discard --> - <column type="gboolean"/> + <column type="gint"/> <!-- column-name break_store_missing --> <column type="gboolean"/> </columns> @@ -2801,7 +2801,7 @@ <property name="spacing">6</property> <child> <object class="GtkCheckButton" id="program_temp_breakpoint"> - <property name="label" translatable="yes">_Temporary breakpoint at:</property> + <property name="label" translatable="yes">_Temporary breakpoint on load at:</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property>
Modified: scope/docs/codes.html 2 files changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -60,7 +60,7 @@ <td class="tab">full breakpoint list refresh (without token is partial)</td></tr>
<tr><td class="nowrap">02-break-insert -t</td> - <td class="tab">Insert <em>Temporary breakpoint at</em></td> + <td class="tab"><em>Temporary breakpoint on load at</em></td> <td class="tab">mark for discard</td></tr>
<tr><td class="nowrap">020-break-insert -t</td>
Modified: scope/docs/scope.html 128 files changed, 69 insertions(+), 59 deletions(-) =================================================================== @@ -8,7 +8,6 @@ <style type="text/css"> .tab { padding-left:1em; } .tab1 { padding-left:1.5em; } - .tab2 { padding-left:2em; } </style> </head>
@@ -80,7 +79,7 @@ <p>Scope is a graphical <a href="http://www.gnu.org/software/gdb">GDB</a> front-end with the normal functions you would expect (stepping, breakpoints...), and a few notable features:</p> <ul> -<li>The comminication between Scope and gdb is asynchronous.</li> +<li>The entire comminication between Scope and gdb is asynchronous.</li> <li>You can enter any gdb command, at any time (of course, for the command to be executed, gdb must be[come] available).</li> <li>All gdb I/O (along with some other messages) is displayed in a terminal-like "Debug @@ -102,11 +101,13 @@
<h3><a name="requirements">Requirements</a></h3>
-<p>Geany 1.22 or later and the respective libraries, including VTE under *nix.</p> +<p>Geany 1.22 or later and the respective libraries.</p>
<p>GDB 7.3 or later.</p>
-<p>win~1: XP or later.</p> +<p>*nix only: VTE library.</p> + +<p>Windows only: XP or later.</p>
<p>GDB manual (recommended).</p>
@@ -117,7 +118,7 @@ <p>From the main Geany menu, invoke <em>Debug --> Setup Program</em> (or <em>Tools --> Debug --> Setup Program</em>, if there's no <em>Debug</em> in the main menu).<br> Choose some small executable file compiled with gdb debug information.<br> -Check <em>Temporary breakpoint at</em> and press <em>OK</em>.<br> +Check <em>Temporary breakpoint on load at</em> and press <em>OK</em>.<br> Invoke <em>Debug --> Run/Continue</em>.</p>
<div>If everything went all right, several things will happen:</div> @@ -128,7 +129,7 @@ neccessary<br> - The first line of code will be marked with brown arrow in the markers margin, or with brown background<br> -- All source files will be marked as read-only (their tabs will turn green)<br> +- All source files will be marked as read-only (their tab text will become green)<br> - The <em>Load</em> label will be replaced with a color-less <em>Debug</em>. </div>
@@ -143,11 +144,12 @@
<ul> <li>Debug menu in the main Geany menu, containing the most commonly used commands (running, -stepping, toggle breakpoint etc.) If Scope can't access the main menu, it'll place Debug under -Tools.</li> +stepping, toggle breakpoint etc.)<br> +If Scope can't access the main menu, it'll place Debug under Tools.</li> <li>Debug page in the lower panel, with subpages that display the program output, threads, breakpoints etc.</li> -<li>Inspect and Registers page in the side panel.</li> +<li>Inspect and Registers pages in the side panel.</li> +<li>Local menus for the Debug subpages, Inspect and Registers.</li> <li>Toolbar items - identical to their Debug menu counterparts.</li> <li>Command Dialog - to enter gdb commands. Will be closed automatically if gdb exits.</li> <li>A small label on the right of your Geany status bar, which displays the current debugging @@ -170,12 +172,11 @@ program is not started yet, or is already terminated. Scope will automatically switch to this state in some situations.</td></tr> <tr><td>(blinking)</td><td class="tab"></td><td class="tab">Loading a program, signal -received, error parsing gdb output, the requested action can not be performed in the current -debug state etc.</td></tr> +received, error parsing gdb output etc.</td></tr> </table> The bracketed letters are used to indicate the states supported by a command. For example, -[RH] means "available in Ready and Hang states only". Debug and Assem are states are almost -identical in this aspect and share [D].</li> +[RH] means "available in Ready and Hang states only". Debug and Assem are almost identical in +this aspect and share [D].</li> </ul>
<h3><a name="debug_menu">Debug menu</a></h3> @@ -187,30 +188,30 @@
<p><em>Arguments</em> are in gdb syntax.</p>
-<p><em>Environment</em> is one var=value per line.</p> +<p><em>Environment</em> is one varname=value per line.</p>
-<p><em>Load script</em> is a gdb script file to be executed when gdb is loaded, before -running the program (see <a href="#run_continue">Run/Continue</a>). If this script contains a -gdb run command, it should contain at least one breakpoint command as well, because all Scope -breakpoints are applied after the program is loaded - and it may be loaded by the script.</p> +<p><em>Load script</em> is a gdb script, executed when gdb is loaded. May be used to setup the +program. If no <em>Executable</em> is specified, Scope will assume that the script, if any, +loads the program.</p>
<p><em><a name="auto_run_exit">Auto run program/exit gdb</a></em> - with this box unchecked, the first <a href="#run_continue">Run/Continue</a> will load and setup the program without -running it; and when the program terminates, gdb will not be unloaded. This is useful if you -want to run a program several times without reloading, for example to run it unmodified with -different sets of input data.</p> +running it, and when the program terminates, gdb will not be unloaded. Useful if you want to +run a program several times without reloading, for example to run it unmodified with different +sets of input data.</p>
<p><em>Non-stop mode</em> - gdb non-stop mode. You'd better activate gdb asynchronous mode from Scope preferences to take advantage of this.</p>
-<p><em>Temporary breakpoint at</em> - set a temporary breakpoint after the program is loaded. -If you leave the text field empty, Scope will try to detect the 1st line of code and place a -breakpoint on it. Any breakpoint options and location are allowed, for example <em>main</em> -for C/C++ programs. Since setting a breakpoint requires a program, temporary breakpoint will -be disabled if both <em>Executable</em> and <em>Load script</em> are empty.</p> +<p><em>Temporary breakpoint on load at</em> - set a temporary breakpoint when the program is +loaded. If you leave the text field empty, Scope will try to detect the 1st line of code and +place a breakpoint on it. Any breakpoint options and location are allowed in the text, for +example <em>main</em> for C/C++ programs. Since setting a breakpoint requires a program, the +temporary breakpoint on load will be disabled if both <em>Executable</em> and <em>Load +script</em> are empty. </p>
<p><em>Delete all breakpoints, watches and inspects</em> - usually when setting up a new -program. Scope will ask you to confirm.</p> +program. Scope will ask for confirmation.</p>
<p><em>Update all views</em> - update all relevant debug subpages when the current thread stops, or a different thread is selected. By default, only the current subpage is updated.</p> @@ -227,34 +228,30 @@
<p>When you start Geany, or open/close a project, Scope will try to load the debugging settings for a program that matches the second <em>Execute</em> command, if any [N]. The -command will not be expanded. Letter case will be ignored under win~1.</p> +command will not be expanded. Letter case will be ignored under Windows.</p>
<p><b><a name="run_continue">Run/Continue</a></b> [NHD]</p>
<div>Not debugging state (first run):</div> <div class="tab"> -- Checks the <em>Program</em> and <em>Working dir</em>, if any - they must exist and be -user-executable at this point<br> -- Checks the <em>Load script</em>, if any - it must exist and be readable<br> -- Loads gdb<br> -- Setups the asynchronous and/or non-stop modes<br> -- Loads the <em>Program</em>, if any<br> -- Executes the <em>Load script</em>, if any<br> -- If either a program was loaded, or a load script was executed without errors:<br> +- Load and setup gdb<br> +- Load the <em>Executable</em> and execute the <em>Load script</em>, if any<br> +- If an executable and/or a load script was processed, and there were no errors so far:<br> <div class="tab1"> - • applies any breakpoints and inspects marked as <em>Apply on Run</em><br> - • applies the temporary breakpoint, if any<br> - • runs the program if, and only if: - <div class="tab2"> - - <em>Auto run/exit</em> is checked<br> - - at least 1 breakpoint was applied<br> - - there were no errors in any of the previous steps. - </div> + • apply any points and inspects marked as <em>Apply on Run</em> and create the + <em>Temporary breakpoint on load</em><br> + • run the program if <em>Auto run/exit</em> is checked, at least 1 breakpoint was + applied, and there weren't any errors. </div> </div>
-<p>Hang state: -exec-run. The temporary breakpoint, if any, will not be applied.<br> -Debug/Assem: -exec-continue.</p> +<p>On errors, Scope will enter Hang state, letting you execute commands manually, and fix or +recreate any points or inspects if needed.</p> + +<p>Hang state: try to apply any unapplied points or inspects marked as <em>Apply on Run</em>, +and -exec-run despite any errors.</p> + +<p>Debug/Assem: -exec-continue.</p>
<p><b><a name="goto_cursor">Run to Cursor</a></b> [D]</p>
@@ -272,11 +269,11 @@
<p><b><a name="terminate">Terminate</a></b> [^N]</p>
-<p>Busy state: kill gdb, even if <a href="#auto_run_exit">Auto Run/exit is unchecked</a>. If -you want to kill the program only, switch to <em>Threads</em> and use <em>Terminate</em> or -<em>Send Signal</em>.</p> +<p>Busy state: terminate gdb, even if <em>Auto Run/exit</em> is unchecked.<br> +If you want to terminate the program without unloading gdb, switch to <em>Threads</em> and +invoke <em>Terminate</em> or <em>Send Signal</em>.</p>
-<p>Debug or Ready state with <em>Auto Run/Exit</em> off: gdb kill command.</p> +<p>Debug or Ready state with <em>Auto Run/Exit</em> off: (gdb) kill.</p>
<p>Otherwise: -gdb-exit.</p>
@@ -284,6 +281,8 @@
<p>Commands starting with 0<digit> are used internally by Scope and will be blocked.</p>
+<p>Both MI and CLI commands are supported.</p> + <p>Scope tries to keep track of the current gdb thread, and to emit a -thread-select command on <em>Send</em>/<em>Busy</em> if the gdb thread does not match the one (if any) selected in <em>Threads</em>. Tracking the current gdb frame asynchronously is impossible, so you must use @@ -293,7 +292,7 @@
<p><b><a name="reset markers">Reset Markers</a></b></p>
-<p>Synchronizes the breakpoint and execution point markers for the current file with the Scope +<p>Synchronize the breakpoint and execution point markers for the current file with the Scope data. They can become out of sync if you <em>Save as</em> a file with markers, set a source file type to non-source and edit it, and possibly in other situations.</p>
@@ -363,11 +362,22 @@ Breakpoint</em>, edit the <em>Ignore</em>, <em>Condition</em> and <em>Script</em> columns, or invoke <em>Add Break / Add Watch</em> [HRD], which brings up the command dialog.</p>
-<div>Only points created with MI commands are kept in the list permanently.<br> -Due to MI limitations and deficiencies:</div> +<p>Breakpoints created with MI commands are kept in the list permanently. When a temporary MI +breakpoint is hit, it's Id column is cleared. <em>Toggle breakpoint</em>, <em>Add Break</em> +and <em>Add Watch</em> use MI commands.</p> + +<p>Breakpoints created with CLI commands (from scripts or <em>GDB Command</em>) are removed +when the program is unloaded. When a temporary CLI breakpoint is hit, it's removed. If a MI +command produces none or invalid output, and the breapoint appears later (from Refresh or +async message), Scope will consider it CLI.</p> + +<p>The above paragraphs apply to watchpoints and tracepoints as well.</p> + +<div>Due to MI limitations and deficiencies:</div> <div class="tab"> -- The catchpoints are displayed incompletely<br> -- Disposition "dis" is ignored, and "del" is saved for breakpoints and tracepoints only<br> +- The catchpoints are displayed incompletely and removed on program unload<br> +- Disposition "dis" is ignored, and "del" (i.e. temporary) is saved for break and trace points +only<br> - The difference between software and hardware watchpoints is ignored, but gdb will create hardware watchpoints as needed.</div>
@@ -396,8 +406,8 @@ <p>For multi-address breakpoints, the individual locations are not loaded or saved, and are deleted as soon as the program is unloaded, so you may prefer to turn <em>Auto run/exit</em> off when using them. When a breakpoint is disabled, GDB treats all it's locations as disabled, -despite their individual state. However, with at least enabled location for a file:line, the -marker for enabled breakpoint will be used for that line.</p> +despite their individual state. However, with at least one enabled location for a file:line, +the marker for enabled breakpoint will be used for that line.</p>
<p><b><a name="stack">Stack</a></b></p>
@@ -584,7 +594,7 @@
<h3><a name="notes">Notes</a></h3>
-<p>Debug Console ignores VTE foreground color, except for the cursor.</p> +<p>Changes in Geany VTE preferences will be applied when Scope is restarted.</p>
<p>Locale/UTF-8 conversion is fully supported for values only. Filenames not matching your locale and non-ascii identifiers are not guaranteed to work.</p> @@ -748,7 +758,7 @@
<b><a name="copyright">Copyright</a></b>
-<p>Scope 0.93, Copyright (C) 2013 Dimitar Toshkov Zhekov</p> +<p>Scope 0.93.1, Copyright (C) 2013 Dimitar Toshkov Zhekov</p>
<p>The menu and toolbar icons are from <a href="http://netbeans.org">Netbeans</a>, except for BreakPoint.</p>
Modified: scope/src/break.c 221 files changed, 154 insertions(+), 67 deletions(-) =================================================================== @@ -74,11 +74,12 @@ static gint break_location_compare(ScpTreeStore *store, GtkTreeIter *a, GtkTreeI }
static const char - *const BP_CHARS = "bhtfwwwaarrc?", + *const BP_TYPES = "bhtfwwwaarrc?", *const BP_BREAKS = "bh", *const BP_TRACES = "tf", *const BP_HARDWS = "hf", *const BP_BORTS = "bhtf", + *const BP_WHATS = "warc", *const BP_KNOWNS = "btfwar", *const BP_WATCHES = "war", *const BP_WATOPTS = "ar"; @@ -87,38 +88,79 @@ static gint break_location_compare(ScpTreeStore *store, GtkTreeIter *a, GtkTreeI { const char *text; const char *type; + const gchar *desc; } BreakType;
static const BreakType break_types[] = { - { "breakpoint", "break" }, - { "hw breakpoint", "hbreak" }, - { "tracepoint", "trace" }, - { "fast tracepoint", "ftrace" }, - { "wpt", "watch" }, - { "watchpoint", "watch" }, - { "hw watchpoint", "watch" }, - { "hw-awpt", "access" }, - { "acc watchpoint", "access" }, - { "hw-rwpt", "read" }, - { "read watchpoint", "read" }, - { "catchpoint", "catch" }, - { NULL, "??" } + { "breakpoint", "break", N_("breakpoint") }, + { "hw breakpoint", "hbreak", N_("hardware breakpoint")}, + { "tracepoint", "trace", N_("tracepoint") }, + { "fast tracepoint", "ftrace", N_("fast tracepoint") }, + { "wpt", "watch", N_("write watchpoint") }, + { "watchpoint", "watch", NULL }, + { "hw watchpoint", "watch", NULL }, + { "hw-awpt", "access", N_("access watchpoint") }, + { "acc watchpoint", "access", NULL }, + { "hw-rwpt", "read", N_("read watchpoint") }, + { "read watchpoint", "read", NULL }, + { "catchpoint", "catch", N_("catchpoint") }, + { NULL, "??", NULL } +}; + +typedef enum _BreakStage +{ + BG_PERSIST, + BG_DISCARD, + BG_UNKNOWN, + BG_PARTLOC, + BG_APPLY, + BG_FOLLOW, + BG_ONLOAD, + BG_RUNTO, + BG_COUNT +} BreakStage; + +typedef struct _BreakInfo +{ + char info; + const char *text; +} BreakInfo; + +static const BreakInfo break_infos[BG_COUNT] = +{ + { '\0', NULL }, + { 'c', N_("CLI") }, + { 'u', N_("unsupported MI") }, + { '\0', NULL }, + { '\0', NULL }, + { 'c', N_("CLI") }, + { 'l', N_("on load") }, + { 'r', N_("Run to Cursor") } };
static void break_type_set_data_func(G_GNUC_UNUSED GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata) { - char type; + char type, info; + gint discard; gboolean temporary; GString *string = g_string_sized_new(0x0F);
- gtk_tree_model_get(model, iter, BREAK_TYPE, &type, BREAK_TEMPORARY, &temporary, -1); - g_string_append(string, break_types[strchr(BP_CHARS, type) - BP_CHARS].type); + gtk_tree_model_get(model, iter, BREAK_TYPE, &type, BREAK_TEMPORARY, &temporary, + BREAK_DISCARD, &discard, -1); + g_string_append(string, break_types[strchr(BP_TYPES, type) - BP_TYPES].type); + info = break_infos[discard].info;
- if (temporary) - g_string_append(string, ",t"); + if (info || temporary) + { + g_string_append_c(string, ','); + if (info) + g_string_append_c(string, info); + if (temporary) + g_string_append_c(string, 't'); + }
g_object_set(cell, "text", string->str, NULL); g_string_free(string, TRUE); @@ -249,15 +291,6 @@ static void append_script_command(const ParseNode *node, GString *string) } }
-typedef enum _BreakStage -{ - BG_PERSIST, - BG_DISCARD, - BG_APPLY, - BG_GOTO, - BG_NEXT -} BreakStage; - typedef struct _BreakData { GtkTreeIter iter; @@ -333,9 +366,9 @@ static void break_node_parse(const ParseNode *node, BreakData *bd) if (!strcmp(text_type, bt->text)) break;
- type = BP_CHARS[bt - break_types]; + type = BP_TYPES[bt - break_types];
- if (leading || bd->stage != BG_NEXT || type != '?') + if (leading || bd->stage != BG_FOLLOW || type != '?') bd->type = type; else type = bd->type; @@ -358,7 +391,6 @@ static void break_node_parse(const ParseNode *node, BreakData *bd) const char *location = parse_find_locale(nodes, "original-location"); char *original = g_strdup(location); gchar *display; - gboolean persist = leading && bd->stage == BG_PERSIST; gboolean pending = parse_find_locale(nodes, "pending") != NULL;
if (original) @@ -377,7 +409,7 @@ static void break_node_parse(const ParseNode *node, BreakData *bd) loc.line = atoi(split); } } - else if (strchr(BP_WATCHES, type)) + else if (strchr(BP_WHATS, type)) { if ((location = parse_find_locale(nodes, "exp")) == NULL) location = parse_find_locale(nodes, "what"); @@ -385,7 +417,9 @@ static void break_node_parse(const ParseNode *node, BreakData *bd)
if (!location || !strchr(BP_KNOWNS, type)) { - persist = FALSE; /* can't create apply command */ + if (bd->stage == BG_PERSIST) + bd->stage = BG_UNKNOWN; /* can't create apply command */ + if (!location) location = loc.func; } @@ -405,9 +439,9 @@ static void break_node_parse(const ParseNode *node, BreakData *bd) scp_tree_store_set(store, iter, BREAK_SCID, ++scid_gen, BREAK_TYPE, type, BREAK_DISPLAY, display, BREAK_PENDING, pending, BREAK_LOCATION, location, BREAK_RUN_APPLY, leading && borts, - BREAK_DISCARD, !persist, -1); + BREAK_DISCARD, leading ? bd->stage : BG_PARTLOC, -1);
- if (persist) + if (leading && bd->stage == BG_PERSIST) utils_tree_set_cursor(selection, iter, 0.5);
g_free(original); @@ -455,10 +489,10 @@ static void break_node_parse(const ParseNode *node, BreakData *bd)
if (bd->stage == BG_APPLY) break_iter_applied(iter, id); - else if (bd->stage == BG_GOTO) + else if (bd->stage == BG_RUNTO) debug_send_thread("-exec-continue");
- bd->stage = BG_NEXT; + bd->stage = BG_FOLLOW; } }
@@ -472,7 +506,7 @@ void on_break_inserted(GArray *nodes) if (token) { if (*token == '0') - bd.stage = BG_GOTO; + bd.stage = BG_RUNTO; else if (*token) { iff (store_find(store, &bd.iter, BREAK_SCID, token), "%s: b_scid not found", @@ -482,7 +516,7 @@ void on_break_inserted(GArray *nodes) } } else - bd.stage = BG_DISCARD; + bd.stage = BG_ONLOAD; }
parse_foreach(nodes, (GFunc) break_node_parse, &bd); @@ -570,7 +604,7 @@ static gboolean break_remove_all(const char *pref, gboolean force) while (valid) { const char *id; - gboolean discard; + gint discard;
scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_DISCARD, &discard, -1);
@@ -578,7 +612,7 @@ static gboolean break_remove_all(const char *pref, gboolean force) { found = TRUE;
- if (discard || force) + if (discard % BG_ONLOAD || force) { valid = break_remove(&iter); continue; @@ -638,14 +672,15 @@ static void breaks_missing(void) while (valid) { const char *id; - gboolean discard, missing; + gint discard; + gboolean missing;
scp_tree_store_get(store, &iter, BREAK_ID, &id, BREAK_DISCARD, &discard, BREAK_MISSING, &missing, -1);
if (id && missing) { - if (discard) + if (discard % BG_ONLOAD) { valid = break_remove(&iter); continue; @@ -760,7 +795,7 @@ void breaks_clear(void)
while (valid) { - gboolean discard; + gint discard;
scp_tree_store_get(store, &iter, BREAK_DISCARD, &discard, -1);
@@ -786,11 +821,12 @@ void breaks_reset(void)
static void break_iter_apply(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata) { + const char *id; gboolean run_apply;
- scp_tree_store_get(store, iter, BREAK_RUN_APPLY, &run_apply, -1); + scp_tree_store_get(store, iter, BREAK_ID, &id, BREAK_RUN_APPLY, &run_apply, -1);
- if (run_apply) + if (run_apply && !id) break_apply(iter, FALSE); }
@@ -1014,7 +1050,7 @@ void breaks_load(GKeyFile *config)
static gboolean break_save(GKeyFile *config, const char *section, GtkTreeIter *iter) { - gboolean discard; + gint discard;
scp_tree_store_get(store, iter, BREAK_DISCARD, &discard, -1);
@@ -1090,41 +1126,91 @@ static void on_break_selection_changed(GtkTreeSelection *selection, }
static GtkTreeView *tree; +static GtkTreeViewColumn *break_type_column; +static GtkTreeViewColumn *break_display_column;
static gboolean on_break_query_tooltip(G_GNUC_UNUSED GtkWidget *widget, gint x, gint y, - gboolean keyboard_tip, GtkTooltip *tooltip, GtkTreeViewColumn *break_display_column) + gboolean keyboard_tip, GtkTooltip *tooltip, G_GNUC_UNUSED gpointer gdata) { + GtkTreePath *path; GtkTreeIter iter; gboolean has_tip = FALSE;
- if (gtk_tree_view_get_tooltip_context(tree, &x, &y, keyboard_tip, NULL, NULL, &iter)) + if (gtk_tree_view_get_tooltip_context(tree, &x, &y, keyboard_tip, NULL, &path, &iter)) { - const char *file, *func; - gint line; GString *text = g_string_sized_new(0xFF); + GtkTreeViewColumn *tip_column = NULL;
- gtk_tree_view_set_tooltip_cell(tree, tooltip, NULL, break_display_column, NULL); - scp_tree_store_get(store, &iter, BREAK_FILE, &file, BREAK_LINE, &line, BREAK_FUNC, - &func, -1); - - if (file) + if (keyboard_tip) + gtk_tree_view_get_cursor(tree, NULL, &tip_column); + else { - g_string_append(text, file); - if (line) - g_string_append_printf(text, ":%d", line); - has_tip = TRUE; + GdkRectangle rect; + GdkRegion *region; + + gtk_tree_view_get_background_area(tree, path, break_type_column, &rect); + region = gdk_region_rectangle(&rect); + tip_column = gdk_region_point_in(region, x, y) ? break_type_column : NULL; + gdk_region_destroy(region); + + if (!tip_column) + { + gtk_tree_view_get_background_area(tree, path, break_display_column, + &rect); + region = gdk_region_rectangle(&rect); + if (gdk_region_point_in(region, x, y)) + tip_column = break_display_column; + gdk_region_destroy(region); + } }
- if (func) + if (tip_column == break_type_column) { - if (has_tip) - g_string_append(text, ", "); - g_string_append_printf(text, "%s()", func); + char type; + gint discard; + gboolean temporary; + + gtk_tree_view_set_tooltip_cell(tree, tooltip, NULL, tip_column, NULL); + scp_tree_store_get(store, &iter, BREAK_TYPE, &type, BREAK_TEMPORARY, + &temporary, BREAK_DISCARD, &discard, -1); + g_string_append(text, break_types[strchr(BP_TYPES, type) - BP_TYPES].desc); has_tip = TRUE; + + if (break_infos[discard].text) + g_string_append_printf(text, _(", %s"), break_infos[discard].text); + + if (temporary) + g_string_append(text, ", temporary"); + } + else if (tip_column == break_display_column) + { + const char *file, *func; + gint line; + + gtk_tree_view_set_tooltip_cell(tree, tooltip, NULL, tip_column, NULL); + scp_tree_store_get(store, &iter, BREAK_FILE, &file, BREAK_LINE, &line, + BREAK_FUNC, &func, -1); + + if (file) + { + g_string_append(text, file); + if (line) + g_string_append_printf(text, ":%d", line); + has_tip = TRUE; + } + + if (func) + { + if (has_tip) + g_string_append(text, ", "); + g_string_append_printf(text, _("func %s"), func); + has_tip = TRUE; + } }
gtk_tooltip_set_text(tooltip, text->str); g_string_free(text, TRUE); + gtk_tree_path_free(path); }
return has_tip; @@ -1288,8 +1374,10 @@ void break_init(void) GtkWidget *menu; guint i;
+ break_type_column = get_column("break_type_column"); + break_display_column = get_column("break_display_column"); tree = view_connect("break_view", &store, &selection, break_cells, "break_window", NULL); - gtk_tree_view_column_set_cell_data_func(get_column("break_type_column"), + gtk_tree_view_column_set_cell_data_func(break_type_column, GTK_CELL_RENDERER(get_object("break_type")), break_type_set_data_func, NULL, NULL); g_signal_connect(get_object("break_ignore"), "editing-started", G_CALLBACK(on_break_ignore_editing_started), NULL); @@ -1301,8 +1389,7 @@ void break_init(void) block_cells[i] = get_object(break_cells[i + 1].name); g_signal_connect(selection, "changed", G_CALLBACK(on_break_selection_changed), NULL); gtk_widget_set_has_tooltip(GTK_WIDGET(tree), TRUE); - g_signal_connect(tree, "query-tooltip", G_CALLBACK(on_break_query_tooltip), - get_column("break_display_column")); + g_signal_connect(tree, "query-tooltip", G_CALLBACK(on_break_query_tooltip), NULL);
menu = menu_select("break_menu", &break_menu_info, selection); g_signal_connect(tree, "key-press-event", G_CALLBACK(on_break_key_press), NULL);
Modified: scope/src/debug.c 4 files changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -630,7 +630,11 @@ void on_debug_run_continue(G_GNUC_UNUSED const MenuItem *menu_item) else if (thread_count) debug_send_thread("-exec-continue"); else + { + breaks_apply(); + inspects_apply(); debug_send_command(N, "-exec-run"); + } }
void on_debug_goto_cursor(G_GNUC_UNUSED const MenuItem *menu_item)
Modified: scope/src/gtk216.c 4 files changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -35,7 +35,7 @@ void gtk_widget_set_visible(GtkWidget *widget, gboolean visible) gint sort_column_id; } SortColumnId;
-static SortColumnId sort_column_ids[] = +static const SortColumnId sort_column_ids[] = { { "thread_id_column", 0 }, { "thread_pid_column", 3 }, @@ -71,7 +71,7 @@ void gtk_widget_set_visible(GtkWidget *widget, gboolean visible)
void gtk216_init(void) { - SortColumnId *scd; + const SortColumnId *scd;
for (scd = sort_column_ids; scd->id; scd++) gtk_tree_view_column_set_sort_column_id(get_column(scd->id), scd->sort_column_id);
Modified: scope/src/inspect.c 8 files changed, 4 insertions(+), 4 deletions(-) =================================================================== @@ -569,13 +569,13 @@ gboolean inspects_update(void)
static void inspect_iter_apply(GtkTreeIter *iter, G_GNUC_UNUSED gpointer gdata) { - const char *frame; + const char *var1, *frame; gboolean run_apply;
- scp_tree_store_get(store, iter, INSPECT_FRAME, &frame, INSPECT_RUN_APPLY, &run_apply, - -1); + scp_tree_store_get(store, iter, INSPECT_VAR1, &var1, INSPECT_FRAME, &frame, + INSPECT_RUN_APPLY, &run_apply, -1);
- if (run_apply && !isdigit(*frame)) + if (run_apply && !var1 && !isdigit(*frame)) inspect_apply(iter); }
Modified: scope/src/scope.c 5 files changed, 2 insertions(+), 3 deletions(-) =================================================================== @@ -214,8 +214,6 @@ static void toolbar_update_state(DebugState state) static GtkWidget *debug_statusbar; static GtkLabel *debug_state_label;
-static DebugState last_statusbar_state; - void statusbar_update_state(DebugState state) { static DebugState last_state = DS_INACTIVE; @@ -326,7 +324,7 @@ static gboolean settings_saved(gpointer gdata) SCI_GETREADONLY, 0, 0); }
- if (GPOINTER_TO_INT(gdata)) + if (gdata) { conterm_load_config(); conterm_apply_config(); @@ -550,6 +548,7 @@ void plugin_init(G_GNUC_UNUSED GeanyData *gdata) if (!gtk_builder_add_from_file(builder, gladefile, &gerror)) { msgwin_status_add(_("Scope: %s."), gerror->message); + g_warning(_("Scope: %s."), gerror->message); g_error_free(gerror); g_object_unref(builder); builder = NULL;
Modified: scope/src/watch.c 4 files changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -57,7 +57,7 @@ static void watch_iter_update(GtkTreeIter *iter, gpointer gdata) scp_tree_store_get(store, iter, WATCH_EXPR, &expr, WATCH_SCID, &scid, WATCH_ENABLED, &enabled, -1);
- if (enabled || GPOINTER_TO_INT(gdata)) + if (enabled || gdata) g_free(debug_send_evaluate('6', scid, expr)); }
@@ -147,7 +147,7 @@ gboolean watches_update(void) if (view_frame_update()) return FALSE;
- store_foreach(store, (GFunc) watch_iter_update, GPOINTER_TO_INT(FALSE)); + store_foreach(store, (GFunc) watch_iter_update, NULL); return TRUE; }
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).