[geany/geany-plugins] 601b1c: breakpoint improvements and other changes, version 0.93.1

Dimitar Zhekov git-noreply at xxxxx
Mon Jan 6 18:50:59 UTC 2014


Branch:      refs/heads/master
Author:      Dimitar Zhekov <dimitar.zhekov at gmail.com>
Committer:   Dimitar Zhekov <dimitar.zhekov at gmail.com>
Date:        Mon, 06 Jan 2014 18:50:59 UTC
Commit:      601b1cf5c611aaad0bfb8210396a3991e03c8f78
             https://github.com/geany/geany-plugins/commit/601b1cf5c611aaad0bfb8210396a3991e03c8f78

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 at 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 at 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).


More information about the Plugins-Commits mailing list