[geany/geany-plugins] 848f75: scope - register ScpTreeStore dynamically, making Scope unloadable again

Dimitar Zhekov git-noreply at xxxxx
Sat Sep 21 17:46:16 UTC 2013


Branch:      refs/heads/master
Author:      Dimitar Zhekov <dimitar.zhekov at gmail.com>
Committer:   Dimitar Zhekov <dimitar.zhekov at gmail.com>
Date:        Sat, 21 Sep 2013 17:46:16 UTC
Commit:      848f75e48f10ee96f299ffdc5447577c7fa008ee
             https://github.com/geany/geany-plugins/commit/848f75e48f10ee96f299ffdc5447577c7fa008ee

Log Message:
-----------
scope - register ScpTreeStore dynamically, making Scope unloadable again


Modified Paths:
--------------
    scope/ChangeLog
    scope/NOTES
    scope/docs/scope.html
    scope/src/break.c
    scope/src/conterm.c
    scope/src/debug.c
    scope/src/inspect.c
    scope/src/memory.c
    scope/src/menu.c
    scope/src/parse.c
    scope/src/prefs.c
    scope/src/program.c
    scope/src/register.c
    scope/src/scope.c
    scope/src/stack.c
    scope/src/store/ChangeLog
    scope/src/store/fullspeed.html
    scope/src/store/scptreestore.c
    scope/src/store/scptreestore.h
    scope/src/store/scptreestore.html
    scope/src/thread.c
    scope/src/tooltip.c
    scope/src/tooltip.h
    scope/src/views.c

Modified: scope/ChangeLog
19 files changed, 17 insertions(+), 2 deletions(-)
===================================================================
@@ -1,3 +1,18 @@
+2013-07-25  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
+
+ * src/scope.c:
+   Register ScpTreeStore dynamically, making Scope unloadable again.
+ * src/break.c, src/conterm.c, src/debug.c, src/inspect.c,
+   src/memory.c, src/menu.c, src/parse.c, src/program.c,
+   src/register.c, src/scope.c, src/stack.c, src/thread.c,
+   src/tooltip.c, src/tooltip.h, src/views.c:
+   Reverted the startup variable initialization from 2013-07-25.
+ * src/conterm.c, src/inspect.c, src/prefs.c, src/watch.c:
+   Small startup changes.
+ * docs/scope.html, src/scope.c:
+   Increased version to 0.93.
+
+
 2013-09-07  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
 
  * data/scope.glade:
@@ -55,8 +70,8 @@
    src/memory.c, src/menu.c, src/parse.c, src/program.c,
    src/register.c, src/scope.c, src/stack.c, src/thread.c,
    src/tooltip.c, src/tooltip.h, src/views.c:
-   Explicitly initialize all sensitive global and static variables,
-   since reloading the plugin will not do that.
+   Explicitly initialize all sensitive global and static variables on
+   startup, since reactivating a resident plugin will not do that.
  * src/store/scptreestore.c:
    Fixed indentation.
  * docs/scope.html, src/scope.c:


Modified: scope/NOTES
3 files changed, 0 insertions(+), 3 deletions(-)
===================================================================
@@ -1,9 +1,6 @@
 -var-evaluate-expression reports the value from the last -var-update or
 -var-assign execution, not the current value
 
-reloading a resident geany plugin module does not reinitialize any global
-and static variables, so the sensitive ones must be initialized explicitly
-
 register modified is 07 since changing a register ($dh, $mm1.uint64) may
 change another ($dx, $st1), and there is some chance of watches/inspects
 containing a register


Modified: scope/docs/scope.html
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -748,7 +748,7 @@
 
 <b><a name="copyright">Copyright</a></b>
 
-<p>Scope 0.92, Copyright (C) 2013 Dimitar Toshkov Zhekov</p>
+<p>Scope 0.93, 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
4 files changed, 1 insertions(+), 3 deletions(-)
===================================================================
@@ -676,7 +676,7 @@ void on_break_list(GArray *nodes)
 	}
 }
 
-gint break_async;
+gint break_async = -1;
 
 void on_break_stopped(GArray *nodes)
 {
@@ -1288,8 +1288,6 @@ void break_init(void)
 	GtkWidget *menu;
 	guint i;
 
-	break_async = -1;
-
 	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_CELL_RENDERER(get_object("break_type")), break_type_set_data_func, NULL, NULL);


Modified: scope/src/conterm.c
33 files changed, 13 insertions(+), 20 deletions(-)
===================================================================
@@ -28,7 +28,6 @@
 
 #define NFD 5
 #define DS_COPY (DS_BASICS | DS_EXTRA_1)
-static int last_console_fd;
 
 #ifdef G_OS_UNIX
 #if (defined(__unix__) || defined(unix)) && !defined(USG)
@@ -166,22 +165,23 @@ void on_vte_realize(VteTerminal *vte, G_GNUC_UNUSED gpointer gdata)
 #endif
 }
 
-static VteTerminal *debug_console;  /* NULL -> GtkTextView "context" */
+static VteTerminal *debug_console = NULL;  /* NULL -> GtkTextView "context" */
 
 static void console_output(int fd, const char *text, gint length)
 {
 	static const char fd_colors[NFD] = { '6', '7', '1', '7', '5' };
 	static char setaf[5] = { '\033', '[', '3', '?', 'm' };
+	static int last_fd = -1;
 	gint i;
 
-	if (last_console_fd == 3 && fd != 0)
+	if (last_fd == 3 && fd != 0)
 		vte_terminal_feed(debug_console, "\r\n", 2);
 
-	if (fd != last_console_fd)
+	if (fd != last_fd)
 	{
 		setaf[3] = fd_colors[fd];
 		vte_terminal_feed(debug_console, setaf, sizeof setaf);
-		last_console_fd = fd;
+		last_fd = fd;
 	}
 
 	if (length == -1)
@@ -214,20 +214,21 @@ static void console_output_nl(int fd, const char *text, gint length)
 static GtkTextTag *fd_tags[NFD];
 #define DC_LIMIT 32768  /* approx */
 #define DC_DELTA 6144
-static guint dc_chars;
+static guint dc_chars = 0;
 
 void context_output(int fd, const char *text, gint length)
 {
+	static int last_fd = -1;
 	GtkTextIter end;
 	gchar *utf8;
 
 	gtk_text_buffer_get_end_iter(context, &end);
 
-	if (last_console_fd == 3 && fd != 0)
+	if (last_fd == 3 && fd != 0)
 		gtk_text_buffer_insert(context, &end, "\n", 1);
 
-	if (fd != last_console_fd)
-		last_console_fd = fd;
+	if (fd != last_fd)
+		last_fd = fd;
 
 	if (length == -1)
 		length = strlen(text);
@@ -421,8 +422,8 @@ void conterm_apply_config(void)
 }
 
 #ifdef G_OS_UNIX
-static int pty_slave;
-char *slave_pty_name;
+static int pty_slave = -1;
+char *slave_pty_name = NULL;
 #endif
 
 void conterm_init(void)
@@ -434,11 +435,8 @@ void conterm_init(void)
 	char *pty_name;
 #endif
 
-	last_console_fd = -1;
+	conterm_load_config();
 #ifdef G_OS_UNIX
-	pty_slave = -1;
-	slave_pty_name = NULL;
-
 	program_window = get_widget("program_window");
 	console = vte_terminal_new();
 	gtk_widget_show(console);
@@ -535,11 +533,6 @@ void conterm_init(void)
 			"#C0C0C0", "#C000C0" };
 		guint i;
 
-	#ifdef G_OS_UNIX
-		debug_console = NULL;
-	#endif
-		dc_chars = 0;
-
 		console = get_widget("debug_context");
 		context_apply_config(console);
 		debug_context = GTK_TEXT_VIEW(console);


Modified: scope/src/debug.c
7 files changed, 2 insertions(+), 5 deletions(-)
===================================================================
@@ -78,7 +78,7 @@ static int kill(HANDLE pid, int sig)
 	KILLING
 } GdbState;
 
-static GdbState gdb_state;
+static GdbState gdb_state = INACTIVE;
 static GSource *gdb_source;
 static GPid gdb_pid;
 
@@ -266,7 +266,7 @@ static gboolean source_check(G_GNUC_UNUSED GSource *source)
 }
 #endif  /* G_OS_UNIX */
 
-static guint source_id;
+static guint source_id = 0;
 
 static gboolean source_dispatch(G_GNUC_UNUSED GSource *source,
 	G_GNUC_UNUSED GSourceFunc callback, G_GNUC_UNUSED gpointer gdata)
@@ -748,9 +748,6 @@ char *debug_send_evaluate(char token, gint scid, const gchar *expr)
 
 void debug_init(void)
 {
-	gdb_state = INACTIVE;
-	source_id = 0;
-	
 	commands = g_string_sized_new(0x3FFF);
 	received = g_string_sized_new(pref_gdb_buffer_length);
 	MAXLEN = received->allocated_len - 1;


Modified: scope/src/inspect.c
20 files changed, 8 insertions(+), 12 deletions(-)
===================================================================
@@ -163,7 +163,7 @@ static void on_jump_to_menu_item_activate(GtkMenuItem *menuitem, G_GNUC_UNUSED g
 
 static GtkWidget *jump_to_item;
 static GtkContainer *jump_to_menu;
-static gchar *jump_to_expr;
+static gchar *jump_to_expr = NULL;
 
 static void on_inspect_row_inserted(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
 	G_GNUC_UNUSED gpointer gdata)
@@ -480,7 +480,7 @@ static void inspect_node_change(const ParseNode *node, G_GNUC_UNUSED gpointer gd
 	}
 }
 
-static gboolean query_all_inspects;
+static gboolean query_all_inspects = FALSE;
 
 void on_inspect_changelist(GArray *nodes)
 {
@@ -687,10 +687,10 @@ static void on_inspect_display_edited(G_GNUC_UNUSED GtkCellRendererText *rendere
 };
 
 static GObject *inspect_display;
-static gboolean last_state_active;
 
 void inspects_update_state(DebugState state)
 {
+	static gboolean last_active = FALSE;
 	gboolean active = state != DS_INACTIVE;
 	GtkTreeIter iter;
 
@@ -707,11 +707,11 @@ void inspects_update_state(DebugState state)
 		g_object_set(inspect_display, "editable", var1 && !numchild, NULL);
 	}
 
-	if (active != last_state_active)
+	if (active != last_active)
 	{
 		gtk_widget_set_sensitive(jump_to_item, active &&
 			scp_tree_store_get_iter_first(store, &iter));
-		last_state_active = active;
+		last_active = active;
 	}
 }
 
@@ -978,7 +978,7 @@ static void on_inspect_delete(G_GNUC_UNUSED const MenuItem *menu_item)
 
 static MenuItem inspect_menu_items[] =
 {
-	{ "inspect_refresh",   on_inspect_refresh,        DS_DEBUG,      NULL, NULL },
+	{ "inspect_refresh",   on_inspect_refresh,        DS_VARIABLE,   NULL, NULL },
 	{ "inspect_add",       on_inspect_add,            DS_NOT_BUSY,   NULL, NULL },
 	{ "inspect_edit",      on_inspect_edit,           DS_EDITABLE,   NULL, NULL },
 	{ "inspect_apply",     on_inspect_apply,          DS_APPLIABLE,  NULL, NULL },
@@ -1133,10 +1133,6 @@ void inspect_init(void)
 {
 	GtkWidget *menu;
 
-	jump_to_expr = NULL;
-	query_all_inspects = FALSE;
-	last_state_active = FALSE;
-
 	jump_to_item = get_widget("inspect_jump_to_item");
 	jump_to_menu = GTK_CONTAINER(get_widget("inspect_jump_to_menu"));
 	apply_item = menu_item_find(inspect_menu_items, "inspect_apply");
@@ -1155,8 +1151,8 @@ void inspect_init(void)
 	g_signal_connect(selection, "changed", G_CALLBACK(on_inspect_selection_changed), NULL);
 	menu = menu_select("inspect_menu", &inspect_menu_info, selection);
 	g_signal_connect(menu, "show", G_CALLBACK(on_inspect_menu_show), NULL);
-	if (!pref_var_update_bug)
-		inspect_menu_items->state = DS_VARIABLE;
+	if (pref_var_update_bug)
+		inspect_menu_items->state = DS_DEBUG;
 
 	inspect_dialog = dialog_connect("inspect_dialog");
 	inspect_name = GTK_ENTRY(get_widget("inspect_name_entry"));


Modified: scope/src/memory.c
7 files changed, 2 insertions(+), 5 deletions(-)
===================================================================
@@ -117,7 +117,7 @@ static void on_memory_bytes_editing_started(G_GNUC_UNUSED GtkCellRenderer *cell,
 
 static gint back_bytes_per_line;
 static gint bytes_per_line;
-static gint bytes_per_group;
+static gint bytes_per_group = 1;
 
 static void memory_configure(void)
 {
@@ -133,7 +133,7 @@ static void memory_configure(void)
 }
 
 static guint64 memory_start;
-static guint memory_count;
+static guint memory_count = 0;
 #define MAX_BYTES (128 * MAX_BYTES_PER_LINE)  /* +1 incomplete line */
 
 static void write_block(guint64 start, const char *contents, guint count)
@@ -382,9 +382,6 @@ void memory_init(void)
 	GtkWidget *tree = GTK_WIDGET(view_connect("memory_view", &store, &selection,
 		memory_cells, "memory_window", NULL));
 
-	bytes_per_group = 1;
-	memory_count = 0;
-
 	memory_font = *pref_memory_font ? pref_memory_font : pref_vte_font;
 	ui_widget_modify_font_from_string(tree, memory_font);
 	g_signal_connect(get_object("memory_bytes"), "editing-started",


Modified: scope/src/menu.c
10 files changed, 3 insertions(+), 7 deletions(-)
===================================================================
@@ -51,7 +51,7 @@ void menu_item_execute(const MenuInfo *menu_info, const MenuItem *menu_item, gbo
 		plugin_beep();
 }
 
-static gboolean block_execute;
+static gboolean block_execute = FALSE;
 
 void menu_item_set_active(const MenuItem *menu_item, gboolean active)
 {
@@ -109,7 +109,7 @@ static void on_menu_item_activate(GtkMenuItem *menuitem, MenuInfo *menu_info)
 	}
 }
 
-static MenuInfo *active_menu;
+static MenuInfo *active_menu = NULL;
 
 static void update_active_menu(guint state)
 {
@@ -404,7 +404,7 @@ void on_menu_update_boolean(const MenuItem *menu_item)
 	*(gboolean *) menu_item->gdata = gtk_check_menu_item_get_active(item);
 }
 
-static char *input;
+static char *input = NULL;
 static gint eval_mr_mode;
 static gint scid_gen = 0;
 
@@ -519,10 +519,6 @@ void menu_init(void)
 	GList *children = gtk_container_get_children(GTK_CONTAINER(shell));
 	GtkWidget *search2 = find_widget(shell, "search2");
 
-	block_execute = FALSE;
-	active_menu = NULL;
-	input = NULL;
-
 	popup_item = get_widget("popup_item");
 	menu_connect("popup_menu", &popup_menu_info, NULL);
 	g_signal_connect(get_widget("popup_evaluate"), "button-release-event",


Modified: scope/src/parse.c
7 files changed, 2 insertions(+), 5 deletions(-)
===================================================================
@@ -439,8 +439,8 @@ gchar *parse_get_error(GArray *nodes)
 
 #define MAXLEN 0x7FF
 static GString *errors;
-static guint errors_id;
-static guint error_count;
+static guint errors_id = 0;
+static guint error_count = 0;
 
 static gboolean errors_show(G_GNUC_UNUSED gpointer gdata)
 {
@@ -620,9 +620,6 @@ void parse_save(GKeyFile *config)
 
 void parse_init(void)
 {
-	errors_id = 0;
-	error_count = 0;
-
 	errors = g_string_sized_new(MAXLEN);
 	parse_modes = SCP_TREE_STORE(get_object("parse_mode_store"));
 	scp_tree_store_set_sort_column_id(parse_modes, MODE_NAME, GTK_SORT_ASCENDING);


Modified: scope/src/prefs.c
2 files changed, 0 insertions(+), 2 deletions(-)
===================================================================
@@ -309,8 +309,6 @@ void prefs_init(void)
 	g_key_file_free(config);
 	g_free(configfile);
 	g_free(configdir);
-
-	conterm_load_config();
 }
 
 void prefs_finalize(void)


Modified: scope/src/program.c
3 files changed, 1 insertions(+), 2 deletions(-)
===================================================================
@@ -307,7 +307,7 @@ void program_context_changed(void)
 
 #define build_check_execute() (build_get_execute(GEANY_BC_COMMAND) || \
 	build_get_execute(GEANY_BC_WORKING_DIR))
-static gboolean last_state_inactive;
+static gboolean last_state_inactive = TRUE;
 
 void program_update_state(DebugState state)
 {
@@ -442,7 +442,6 @@ void program_init(void)
 	extern gboolean thread_select_on_exited;
 	extern gboolean thread_select_follow;
 
-	last_state_inactive = TRUE;
 	program_dialog = dialog_connect("program_dialog");
 	program_page_vbox = get_widget("program_page_vbox");
 


Modified: scope/src/register.c
7 files changed, 2 insertions(+), 5 deletions(-)
===================================================================
@@ -70,7 +70,7 @@ static void register_node_update(const ParseNode *node, GString *commands[])
 	}
 }
 
-static gboolean query_all_registers;
+static gboolean query_all_registers = TRUE;
 
 static void registers_send_update(GArray *nodes, char token)
 {
@@ -330,7 +330,7 @@ gboolean registers_update(void)
 	return TRUE;
 }
 
-static char *last_gdb_executable;
+static char *last_gdb_executable = NULL;
 
 void registers_query_names(void)
 {
@@ -526,9 +526,6 @@ static void on_register_selection_changed(G_GNUC_UNUSED GtkTreeSelection *select
 
 void register_init(void)
 {
-	query_all_registers = TRUE;
-	last_gdb_executable = NULL;
-
 	tree = GTK_WIDGET(view_connect("register_view", &store, &selection, register_cells,
 		"register_window", &register_display));
 	gtk_widget_set_has_tooltip(tree, TRUE);


Modified: scope/src/scope.c
47 files changed, 18 insertions(+), 29 deletions(-)
===================================================================
@@ -32,7 +32,7 @@
 PLUGIN_VERSION_CHECK(215)
 
 PLUGIN_SET_TRANSLATABLE_INFO(LOCALEDIR, GETTEXT_PACKAGE, _("Scope Debugger"),
-	_("Relatively simple GDB front-end."), "0.92",
+	_("Relatively simple GDB front-end."), "0.93",
 	"Dimitar Toshkov Zhekov <dimitar.zhekov at gmail.com>")
 
 /* Keybinding(s) */
@@ -191,13 +191,12 @@ static void on_toolbar_reconfigured(GtkToolItem *tool_item, ToolItem *item)
 		get_widget(item->icon[large]));
 }
 
-static DebugState last_toolbar_state;
-
 static void toolbar_update_state(DebugState state)
 {
+	static DebugState last_state = 0;
 	state |= debug_menu_extra_state();
 
-	if (state != last_toolbar_state)
+	if (state != last_state)
 	{
 		ToolItem *item;
 
@@ -207,7 +206,7 @@ static void toolbar_update_state(DebugState state)
 				menu_item_matches_state(debug_menu_items + item->index, state));
 		}
 
-		last_toolbar_state = state;
+		last_state = state;
 	}
 }
 
@@ -219,10 +218,12 @@ static void toolbar_update_state(DebugState state)
  
 void statusbar_update_state(DebugState state)
 {
+	static DebugState last_state = DS_INACTIVE;
+
 	if (thread_state == THREAD_AT_ASSEMBLER)
 		state = DS_EXTRA_1;
 
-	if (state != last_statusbar_state)
+	if (state != last_state)
 	{
 		static const char *const states[] = { N_("Busy"), N_("Ready"), N_("Debug"),
 			N_("Hang"), N_("Assem"), N_("Load"), NULL };
@@ -243,7 +244,7 @@ void statusbar_update_state(DebugState state)
 			gtk_statusbar_set_has_resize_grip(geany_statusbar, TRUE);
 		#endif
 		}
-		else if (last_statusbar_state == DS_INACTIVE)
+		else if (last_state == DS_INACTIVE)
 		{
 		#if GTK_CHECK_VERSION(3, 0, 0)
 			gtk_window_set_has_resize_grip(GTK_WINDOW(geany->main_widgets->window), FALSE);
@@ -253,11 +254,11 @@ void statusbar_update_state(DebugState state)
 			gtk_widget_show(debug_statusbar);
 		}
 
-		last_statusbar_state = state;
+		last_state = state;
 	}
 }
 
-static guint blink_id;
+static guint blink_id = 0;
 
 static gboolean plugin_unblink(G_GNUC_UNUSED gpointer gdata)
 {
@@ -313,9 +314,9 @@ static void on_document_open(G_GNUC_UNUSED GObject *obj, GeanyDocument *doc,
 		threads_mark(doc);
 }
 
-static guint after_save_id;
+static guint saved_id = 0;
 
-static gboolean settings_after_save(gpointer gdata)
+static gboolean settings_saved(gpointer gdata)
 {
 	guint i;
 
@@ -331,16 +332,15 @@ static gboolean settings_after_save(gpointer gdata)
 		conterm_apply_config();
 	}
 
-	after_save_id = 0;
+	saved_id = 0;
 	return FALSE;
 }
 
-static void schedule_after_save(gboolean conterm)
+static void schedule_settings_saved(gboolean conterm)
 {
 	guint i;
 
-	after_save_id = plugin_idle_add(geany_plugin, settings_after_save,
-		GINT_TO_POINTER(conterm));
+	saved_id = plugin_idle_add(geany_plugin, settings_saved, GINT_TO_POINTER(conterm));
 
 	foreach_document(i)
 	{
@@ -353,13 +353,13 @@ static void on_settings_save(G_GNUC_UNUSED GObject *obj, G_GNUC_UNUSED GKeyFile
 	G_GNUC_UNUSED gpointer gdata)
 {
 	configure_panel();
-	schedule_after_save(TRUE);
+	schedule_settings_saved(TRUE);
 }
 
 static void on_project_before_save(G_GNUC_UNUSED GObject *obj, G_GNUC_UNUSED GKeyFile *keyfile,
 	G_GNUC_UNUSED gpointer gdata)
 {
-	schedule_after_save(FALSE);
+	schedule_settings_saved(FALSE);
 }
 
 static gboolean on_editor_notify(G_GNUC_UNUSED GObject *obj, GeanyEditor *editor,
@@ -541,21 +541,11 @@ void plugin_init(G_GNUC_UNUSED GeanyData *gdata)
 	ToolItem *tool_item = toolbar_items;
 	const ScopeCallback *scb;
 
-	last_toolbar_state = 0;
-	last_statusbar_state = DS_INACTIVE;
-	blink_id = 0;
-	after_save_id = 0;
-
 	main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
 	scope_key_group = plugin_set_key_group(geany_plugin, "scope", COUNT_KB, NULL);
 	builder = gtk_builder_new();
 	gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE);
-
-	if (!g_type_from_name("ScpTreeStore"))
-	{
-		plugin_module_make_resident(geany_plugin);
-		scp_tree_store_get_type();
-	}
+	scp_tree_store_register_dynamic();
 
 	if (!gtk_builder_add_from_file(builder, gladefile, &gerror))
 	{
@@ -605,7 +595,6 @@ void plugin_init(G_GNUC_UNUSED GeanyData *gdata)
 	conterm_init();
 	inspect_init();
 	register_init();
-	tooltip_init();
 	parse_init();
 	debug_init();
 	views_init();


Modified: scope/src/stack.c
4 files changed, 1 insertions(+), 3 deletions(-)
===================================================================
@@ -62,7 +62,7 @@ static void stack_node_location(const ParseNode *node, const char *fid)
 	}
 }
 
-const char *frame_id;
+const char *frame_id = NULL;
 
 void on_stack_frames(GArray *nodes)
 {
@@ -336,8 +336,6 @@ void stack_init(void)
 	GtkTreeView *tree = view_create("stack_view", &store, &selection);
 	GtkWidget *menu = menu_select("stack_menu", &stack_menu_info, selection);
 
-	frame_id = NULL;
-
 	view_set_sort_func(store, STACK_ID, store_gint_compare);
 	view_set_sort_func(store, STACK_FILE, store_seek_compare);
 	view_set_line_data_func("stack_line_column", "stack_line", STACK_LINE);


Modified: scope/src/store/ChangeLog
14 files changed, 13 insertions(+), 1 deletions(-)
===================================================================
@@ -1,9 +1,21 @@
+2013-09-20  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
+
+ * scptreestore.c, scptreestore.h, scptreestore.html:
+   Added scp_tree_store_register_dynamic().
+ * scptreestore.html, fullspeed.html:
+   Moved the full speed test results to a separate file.
+   Increased version to 0.85.
+ * speed.c:
+   Replaced // with /* */ for glib/gtk+ compliance.
+
 2013-05-16  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
 
  * scptreestore.c, scptreestore.h:
-   Added scp_tree_store_traverse().
    Moved scp_tree_store_iter_tell() from Extra to Store, it's required
    to insert before/after and move.
+   Added scp_tree_store_traverse().
  * scptreestore.html:
    Documentation and speed test results for scp_tree_store_traverse().
    Increased version to 0.84.
+ * speed.c:
+   Added speed test for scp_tree_store_traverse().


Modified: scope/src/store/fullspeed.html
271 files changed, 271 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,271 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>ScpTreeStore full speed test</title>
+<style type="text/css">
+	.tab { padding-left:2em; }
+	table { border-collapse:collapse; }
+	th, td { border: 1px solid black; }
+	.empty { border: 0px; }
+	th, td { padding: 0em 0.5em; }
+</style>
+</head>
+
+<body>
+
+<h2>ScpTreeStore</h2>
+
+<h3>Full speed test</h3>
+
+<p>Notes:</p>
+
+<ul>
+<li>pre/append = prepend for GtkTreeStore (faster than append), and append for<br>
+ScpTreeStore (faster than prepend), though the speed difference is not significant</li>
+<li>all defensive checks are enabled</li>
+<li>all string tests are with utf8 collation</li>
+<li>GtkListStore speed is almost identical to GtkTreeStore, and sometimes slower.</li>
+</ul>
+
+<table>
+<tr><th>Unsorted store</th><th>Row count</th><th>GtkTreeStore</th>
+<th>ScpTreeStore</th><th>Times</th></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level set</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level remove</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>25</td><td>0.000</td><td>0.000</td><td>25</td></tr>
+<tr><td>top-level iter search string</td><td>25</td><td>0.003</td><td>0.002</td><td>25</td></tr>
+<tr><td>top-level linear search double</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
+<tr><td>top-level linear search string</td><td>25</td><td>n/a</td><td>0.001</td><td>25</td></tr>
+<tr><td>both levels model foreach</td><td>25</td><td>0.000</td><td>0.000</td><td>25</td></tr>
+<tr><td>both levels store traverse</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
+<tr><td>top-level quick sort double</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>25</td><td>0.001</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 insert_with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>25</td><td>0.001</td><td>0.001</td><td></td></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level set</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
+<tr><td>top-level remove</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>100</td><td>0.006</td><td>0.000</td><td>100</td></tr>
+<tr><td>top-level iter search string</td><td>100</td><td>0.034</td><td>0.027</td><td>100</td></tr>
+<tr><td>top-level linear search double</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr>
+<tr><td>top-level linear search string</td><td>100</td><td>n/a</td><td>0.015</td><td>100</td></tr>
+<tr><td>both levels model foreach</td><td>100</td><td>0.003</td><td>0.003</td><td>100</td></tr>
+<tr><td>both levels store traverse</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr>
+<tr><td>top-level quick sort double</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>100</td><td>0.003</td><td>0.002</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 insert with values</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>100</td><td>0.005</td><td>0.004</td><td></td></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
+<tr><td>top-level set</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
+<tr><td>top-level remove</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>250</td><td>0.031</td><td>0.003</td><td>250</td></tr>
+<tr><td>top-level iter search string</td><td>250</td><td>0.224</td><td>0.183</td><td>250</td></tr>
+<tr><td>top-level linear search double</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr>
+<tr><td>top-level linear search string</td><td>250</td><td>n/a</td><td>0.109</td><td>250</td></tr>
+<tr><td>both levels model foreach</td><td>250</td><td>0.018</td><td>0.018</td><td>250</td></tr>
+<tr><td>both levels store traverse</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr>
+<tr><td>top-level quick sort double</td><td>250</td><td>0.001</td><td>0.000</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>250</td><td>0.009</td><td>0.008</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
+<tr><td>sublevel 1 insert with values</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>250</td><td>0.002</td><td>0.000</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>250</td><td>0.015</td><td>0.012</td><td></td></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr>
+<tr><td>top-level set</td><td>500</td><td>0.003</td><td>0.002</td><td></td></tr>
+<tr><td>top-level remove</td><td>500</td><td>0.002</td><td>0.001</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>500</td><td>0.003</td><td>0.002</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>500</td><td>0.131</td><td>0.010</td><td>500</td></tr>
+<tr><td>top-level iter search string</td><td>500</td><td>0.909</td><td>0.722</td><td>500</td></tr>
+<tr><td>top-level linear search double</td><td>500</td><td>n/a</td><td>0.005</td><td>500</td></tr>
+<tr><td>top-level linear search string</td><td>500</td><td>n/a</td><td>0.443</td><td>500</td></tr>
+<tr><td>both levels model foreach</td><td>500</td><td>0.077</td><td>0.076</td><td>500</td></tr>
+<tr><td>both levels store traverse</td><td>500</td><td>n/a</td><td>0.003</td><td>500</td></tr>
+<tr><td>top-level quick sort double</td><td>500</td><td>0.003</td><td>0.001</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>500</td><td>0.022</td><td>0.018</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>500</td><td>0.004</td><td>0.002</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr>
+<tr><td>sublevel 1 insert with values</td><td>500</td><td>0.004</td><td>0.003</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>500</td><td>0.005</td><td>0.001</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>500</td><td>0.034</td><td>0.028</td><td></td></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>1000</td><td>0.004</td><td>0.003</td><td></td></tr>
+<tr><td>top-level set</td><td>1000</td><td>0.007</td><td>0.003</td><td></td></tr>
+<tr><td>top-level remove</td><td>1000</td><td>0.004</td><td>0.003</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>1000</td><td>0.007</td><td>0.004</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>1000</td><td>0.052</td><td>0.004</td><td>100</td></tr>
+<tr><td>top-level iter search string</td><td>1000</td><td>0.370</td><td>0.273</td><td>100</td></tr>
+<tr><td>top-level linear search double</td><td>1000</td><td>n/a</td><td>0.002</td><td>100</td></tr>
+<tr><td>top-level linear search string</td><td>1000</td><td>n/a</td><td>0.182</td><td>100</td></tr>
+<tr><td>both levels model foreach</td><td>1000</td><td>0.033</td><td>0.030</td><td>100</td></tr>
+<tr><td>both levels store traverse</td><td>1000</td><td>n/a</td><td>0.001</td><td>100</td></tr>
+<tr><td>top-level quick sort double</td><td>1000</td><td>0.007</td><td>0.002</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>1000</td><td>0.050</td><td>0.040</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>1000</td><td>0.006</td><td>0.004</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>1000</td><td>0.009</td><td>0.005</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>1000</td><td>0.006</td><td>0.004</td><td></td></tr>
+<tr><td>sublevel 1 insert with values</td><td>1000</td><td>0.009</td><td>0.006</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>1000</td><td>0.011</td><td>0.002</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>1000</td><td>0.078</td><td>0.062</td><td></td></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>2500</td><td>0.017</td><td>0.008</td><td></td></tr>
+<tr><td>top-level set</td><td>2500</td><td>0.026</td><td>0.009</td><td></td></tr>
+<tr><td>top-level remove</td><td>2500</td><td>0.019</td><td>0.008</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>2500</td><td>0.026</td><td>0.012</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>2500</td><td>0.340</td><td>0.028</td><td>250</td></tr>
+<tr><td>top-level iter search string</td><td>2500</td><td>2.273</td><td>1.859</td><td>250</td></tr>
+<tr><td>top-level linear search double</td><td>2500</td><td>n/a</td><td>0.015</td><td>250</td></tr>
+<tr><td>top-level linear search string</td><td>2500</td><td>n/a</td><td>1.137</td><td>250</td></tr>
+<tr><td>both levels model foreach</td><td>2500</td><td>0.182</td><td>0.188</td><td>250</td></tr>
+<tr><td>both levels store traverse</td><td>2500</td><td>n/a</td><td>0.009</td><td>250</td></tr>
+<tr><td>top-level quick sort double</td><td>2500</td><td>0.021</td><td>0.004</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>2500</td><td>0.146</td><td>0.117</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>2500</td><td>0.035</td><td>0.014</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>2500</td><td>0.048</td><td>0.014</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>2500</td><td>0.038</td><td>0.013</td><td></td></tr>
+<tr><td>sublevel 1 insert with values</td><td>2500</td><td>0.046</td><td>0.017</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>2500</td><td>0.033</td><td>0.007</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>2500</td><td>0.230</td><td>0.181</td><td></td></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>5000</td><td>0.084</td><td>0.019</td><td></td></tr>
+<tr><td>top-level set</td><td>5000</td><td>0.107</td><td>0.017</td><td></td></tr>
+<tr><td>top-level remove</td><td>5000</td><td>0.089</td><td>0.018</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>5000</td><td>0.103</td><td>0.025</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>5000</td><td>1.271</td><td>0.112</td><td>500</td></tr>
+<tr><td>top-level iter search string</td><td>5000</td><td>8.775</td><td>7.787</td><td>500</td></tr>
+<tr><td>top-level linear search double</td><td>5000</td><td>n/a</td><td>0.060</td><td>500</td></tr>
+<tr><td>top-level linear search string</td><td>5000</td><td>n/a</td><td>4.351</td><td>500</td></tr>
+<tr><td>both levels model foreach</td><td>5000</td><td>0.741</td><td>0.754</td><td>500</td></tr>
+<tr><td>both levels store traverse</td><td>5000</td><td>n/a</td><td>0.042</td><td>500</td></tr>
+<tr><td>top-level quick sort double</td><td>5000</td><td>0.046</td><td>0.010</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>5000</td><td>0.325</td><td>0.264</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>5000</td><td>0.168</td><td>0.040</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>5000</td><td>0.201</td><td>0.038</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>5000</td><td>0.184</td><td>0.038</td><td></td></tr>
+<tr><td>sublevel 1 insert with values</td><td>5000</td><td>0.199</td><td>0.046</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>5000</td><td>0.073</td><td>0.015</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>5000</td><td>0.508</td><td>0.405</td><td></td></tr>
+
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>top-level insert</td><td>10000</td><td>0.410</td><td>0.049</td><td></td></tr>
+<tr><td>top-level set</td><td>10000</td><td>0.465</td><td>0.035</td><td></td></tr>
+<tr><td>top-level remove</td><td>10000</td><td>0.430</td><td>0.045</td><td></td></tr>
+<tr><td>top-level insert with values</td><td>10000</td><td>0.461</td><td>0.059</td><td></td></tr>
+<tr><td>top-level iter search double</td><td>10000</td><td>7.434</td><td>0.509</td><td>1000</td></tr>
+<tr><td>top-level iter search string</td><td>10000</td><td>37.555</td><td>31.020</td><td>1000</td></tr>
+<tr><td>top-level linear search double</td><td>10000</td><td>n/a</td><td>0.304</td><td>1000</td></tr>
+<tr><td>top-level linear search string</td><td>10000</td><td>n/a</td><td>18.896</td><td>1000</td></tr>
+<tr><td>both levels model foreach</td><td>10000</td><td>2.969</td><td>3.136</td><td>1000</td></tr>
+<tr><td>both levels store traverse</td><td>10000</td><td>n/a</td><td>0.238</td><td>1000</td></tr>
+<tr><td>top-level quick sort double</td><td>10000</td><td>0.112</td><td>0.022</td><td></td></tr>
+<tr><td>top-level quick sort string</td><td>10000</td><td>0.720</td><td>0.580</td><td></td></tr>
+<tr><td>sublevel 1 insert</td><td>10000</td><td>1.152</td><td>0.132</td><td></td></tr>
+<tr><td>sublevel 1 set</td><td>10000</td><td>1.730</td><td>0.116</td><td></td></tr>
+<tr><td>sublevel 1 remove</td><td>10000</td><td>1.364</td><td>0.128</td><td></td></tr>
+<tr><td>sublevel 1 insert with values</td><td>10000</td><td>1.427</td><td>0.146</td><td></td></tr>
+<tr><td>sublevel 1 quick sort double</td><td>10000</td><td>0.170</td><td>0.034</td><td></td></tr>
+<tr><td>sublevel 1 quick sort string</td><td>10000</td><td>1.114</td><td>0.893</td><td></td></tr>
+
+<tr><td colspan="5" class="empty"> </td></tr>
+<tr><th>Store sorted by double</th><th>Row count</th><th>GtkTreeStore</th>
+<th>ScpTreeStore</th><th>Times</th></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>25</td><td>0.003</td><td>0.000</td><td></td></tr>
+<tr><td>pre/append with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
+<tr><td>binary search</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>100</td><td>0.004</td><td>0.001</td><td></td></tr>
+<tr><td>pre/append with values</td><td>100</td><td>0.003</td><td>0.000</td><td></td></tr>
+<tr><td>binary search</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>250</td><td>0.019</td><td>0.003</td><td></td></tr>
+<tr><td>pre/append with values</td><td>250</td><td>0.015</td><td>0.001</td><td></td></tr>
+<tr><td>binary search</td><td>250</td><td>n/a</td><td>0.000</td><td>250</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>500</td><td>0.068</td><td>0.007</td><td></td></tr>
+<tr><td>pre/append with values</td><td>500</td><td>0.054</td><td>0.003</td><td></td></tr>
+<tr><td>binary search</td><td>500</td><td>n/a</td><td>0.000</td><td>500</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>1000</td><td>0.225</td><td>0.015</td><td></td></tr>
+<tr><td>pre/append with values</td><td>1000</td><td>0.203</td><td>0.006</td><td></td></tr>
+<tr><td>binary search</td><td>1000</td><td>n/a</td><td>0.001</td><td>1000</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>2500</td><td>1.474</td><td>0.044</td><td></td></tr>
+<tr><td>pre/append with values</td><td>2500</td><td>1.324</td><td>0.015</td><td></td></tr>
+<tr><td>binary search</td><td>2500</td><td>n/a</td><td>0.002</td><td>2500</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>5000</td><td>6.432</td><td>0.115</td><td></td></tr>
+<tr><td>pre/append with values</td><td>5000</td><td>5.624</td><td>0.035</td><td></td></tr>
+<tr><td>binary search</td><td>5000</td><td>n/a</td><td>0.004</td><td>5000</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>10000</td><td>26.967</td><td>0.335</td><td></td></tr>
+<tr><td>pre/append with values</td><td>10000</td><td>23.803</td><td>0.081</td><td></td></tr>
+<tr><td>binary search</td><td>10000</td><td>n/a</td><td>0.009</td><td>10000</td></tr>
+
+<tr><td colspan="5" class="empty"> </td></tr>
+<tr><th>Store sorted by string</th><th>Row count</th><th>GtkTreeStore</th>
+<th>ScpTreeStore</th><th>Times</th></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>25</td><td>0.003</td><td>0.001</td><td></td></tr>
+<tr><td>pre/append with values</td><td>25</td><td>0.001</td><td>0.001</td><td></td></tr>
+<tr><td>binary search</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>100</td><td>0.014</td><td>0.005</td><td></td></tr>
+<tr><td>pre/append with values</td><td>100</td><td>0.014</td><td>0.003</td><td></td></tr>
+<tr><td>binary search</td><td>100</td><td>n/a</td><td>0.002</td><td>100</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>250</td><td>0.092</td><td>0.015</td><td></td></tr>
+<tr><td>pre/append with values</td><td>250</td><td>0.093</td><td>0.009</td><td></td></tr>
+<tr><td>binary search</td><td>250</td><td>n/a</td><td>0.006</td><td>250</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>500</td><td>0.366</td><td>0.034</td><td></td></tr>
+<tr><td>pre/append with values</td><td>500</td><td>0.343</td><td>0.021</td><td></td></tr>
+<tr><td>binary search</td><td>500</td><td>n/a</td><td>0.012</td><td>500</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>1000</td><td>1.415</td><td>0.077</td><td></td></tr>
+<tr><td>pre/append with values</td><td>1000</td><td>1.444</td><td>0.047</td><td></td></tr>
+<tr><td>binary search</td><td>1000</td><td>n/a</td><td>0.028</td><td>1000</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>2500</td><td>9.032</td><td>0.229</td><td></td></tr>
+<tr><td>pre/append with values</td><td>2500</td><td>9.061</td><td>0.134</td><td></td></tr>
+<tr><td>binary search</td><td>2500</td><td>n/a</td><td>0.080</td><td>2500</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>5000</td><td>36.648</td><td>0.521</td><td></td></tr>
+<tr><td>pre/append with values</td><td>5000</td><td>38.045</td><td>0.296</td><td></td></tr>
+<tr><td>binary search</td><td>5000</td><td>n/a</td><td>0.177</td><td>5000</td></tr>
+<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td>pre/apppend + set</td><td>10000</td><td>slow</td><td>1.225</td><td></td></tr>
+<tr><td>pre/append with values</td><td>10000</td><td>slow</td><td>0.654</td><td></td></tr>
+<tr><td>binary search</td><td>10000</td><td>n/a</td><td>0.385</td><td>10000</td></tr>
+
+</table>
+
+</body>
+</html>


Modified: scope/src/store/scptreestore.c
168 files changed, 112 insertions(+), 56 deletions(-)
===================================================================
@@ -147,16 +147,15 @@ ScpTreeStore *scp_tree_store_newv(gboolean sublevels, gint n_columns, GType *typ
 	ScpTreeStore *store;
 
 	g_return_val_if_fail(n_columns > 0, NULL);
-	store = g_object_new(SCP_TYPE_TREE_STORE, NULL);
+	store = g_object_new(SCP_TYPE_TREE_STORE, "sublevels", sublevels != FALSE, NULL);
 
-	if (scp_tree_store_set_column_types(store, n_columns, types))
+	if (!scp_tree_store_set_column_types(store, n_columns, types))
 	{
-		store->priv->sublevels = sublevels;
-		return store;
+		g_object_unref(store);
+		store = NULL;
 	}
 
-	g_object_unref(store);
-	return NULL;
+	return store;
 }
 
 #define scp_tree_model_compare_func ((GtkTreeIterCompareFunc) scp_tree_store_compare_func)
@@ -1796,15 +1795,6 @@ static void scp_tree_store_buildable_init(GtkBuildableIface *iface)
 	iface->custom_finished = scp_tree_store_buildable_custom_finished;
 }
 
-static void scp_tree_store_finalize(GObject *object);
-
-G_DEFINE_TYPE_WITH_CODE(ScpTreeStore, scp_tree_store, G_TYPE_OBJECT,
-	G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL, scp_tree_store_tree_model_init)
-	G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_DRAG_SOURCE, scp_tree_store_drag_source_init)
-	G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_DRAG_DEST, scp_tree_store_drag_dest_init)
-	G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_SORTABLE, scp_tree_store_sortable_init)
-	G_IMPLEMENT_INTERFACE(GTK_TYPE_BUILDABLE, scp_tree_store_buildable_init))
-
 enum
 {
 	PROP_0,
@@ -1815,6 +1805,33 @@ enum
 	PROP_UTF8_COLLATE
 };
 
+static gpointer scp_tree_store_parent_class = NULL;
+
+static GObject *scp_tree_store_constructor(GType type, guint n_construct_properties,
+	GObjectConstructParam *construct_properties)
+{
+	GObject *object = G_OBJECT_CLASS(scp_tree_store_parent_class)->constructor(type,
+		n_construct_properties, construct_properties);
+	ScpTreeStorePrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(object, SCP_TYPE_TREE_STORE,
+		ScpTreeStorePrivate);
+
+	((ScpTreeStore *) object)->priv = priv;
+	while ((priv->stamp = g_random_int()) == 0);  /* we mark invalid iters with stamp 0 */
+	priv->root = g_new0(AElem, 1);
+	priv->roar = g_ptr_array_new();
+	scp_ptr_array_insert_val(priv->roar, 0, priv->root);
+	priv->headers = NULL;
+	priv->n_columns = 0;
+	priv->sort_column_id = GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID;
+	priv->sort_order = GTK_SORT_ASCENDING;
+	priv->sort_func = NULL;
+	priv->toplevel_reserved = 0;
+	priv->sublevel_reserved = 0;
+	priv->sublevel_discard = FALSE;
+	priv->columns_dirty = FALSE;
+	return object;
+}
+
 static void scp_tree_store_get_property(GObject *object, guint prop_id, GValue *value,
 	GParamSpec *pspec)
 {
@@ -1855,6 +1872,8 @@ static void scp_tree_store_set_property(GObject *object, guint prop_id, const GV
 	{
 		case PROP_SUBLEVELS :
 		{
+			priv = G_TYPE_INSTANCE_GET_PRIVATE(object, SCP_TYPE_TREE_STORE,
+				ScpTreeStorePrivate);  /* ctor, store->priv is not assigned */
 			priv->sublevels = g_value_get_boolean(value);
 			break;
 		}
@@ -1890,72 +1909,109 @@ static void scp_tree_store_set_property(GObject *object, guint prop_id, const GV
 #endif
 }
 
-static void scp_tree_store_class_init(ScpTreeStoreClass *class)
+static void scp_tree_store_finalize(GObject *object)
 {
-	GObjectClass *object_class;
+	ScpTreeStore *store = SCP_TREE_STORE(object);
+	ScpTreeStorePrivate *priv = store->priv;
 
-	object_class = (GObjectClass *) class;
-	object_class->finalize = scp_tree_store_finalize;
-	object_class->get_property = scp_tree_store_get_property;
-	object_class->set_property = scp_tree_store_set_property;
+	scp_free_array(store, priv->root->children);
+	g_free(priv->root);
+	g_ptr_array_free(priv->roar, TRUE);
+
+	if (priv->headers)
+		scp_tree_data_headers_free(priv->n_columns, priv->headers);
+
+	G_OBJECT_CLASS(scp_tree_store_parent_class)->finalize(object);
+}
+
+static void scp_tree_store_gobject_init(GObjectClass *class)
+{
+	scp_tree_store_parent_class = g_type_class_peek_parent(class);
+	class->constructor = scp_tree_store_constructor;
+	class->finalize = scp_tree_store_finalize;
+	class->get_property = scp_tree_store_get_property;
+	class->set_property = scp_tree_store_set_property;
+}
+
+static void scp_tree_store_class_init(GObjectClass *class)
+{
+	scp_tree_store_gobject_init(class);
 	g_type_class_add_private(class, sizeof(ScpTreeStorePrivate));
-	g_assert(GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID == -1);
+	g_assert(GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID == -1);  /* headers[-1] = default */
 
-	g_object_class_install_property(object_class, PROP_SUBLEVELS,
+	g_object_class_install_property(class, PROP_SUBLEVELS,
 		g_param_spec_boolean("sublevels", P_("Sublevels"),
 		P_("Supports sublevels (as opposed to flat list)"), TRUE,
 		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-	g_object_class_install_property(object_class, PROP_TOPLEVEL_RESERVED,
+	g_object_class_install_property(class, PROP_TOPLEVEL_RESERVED,
 		g_param_spec_uint("toplevel-reserved", P_("Toplevel reserved"),
 		P_("Number of pointers preallocated for top-level elements"),
 		0, G_MAXINT32, 0, G_PARAM_READWRITE));
 
-	g_object_class_install_property(object_class, PROP_SUBLEVEL_RESERVED,
+	g_object_class_install_property(class, PROP_SUBLEVEL_RESERVED,
 		g_param_spec_uint("sublevel-reserved", P_("Sublevel reserved"),
 		P_("Number of pointers preallocated for sublevel elements"),
 		0, G_MAXINT32, 0, G_PARAM_READWRITE));
 
-	g_object_class_install_property(object_class, PROP_SUBLEVEL_DISCARD,
+	g_object_class_install_property(class, PROP_SUBLEVEL_DISCARD,
 		g_param_spec_boolean("sublevel-discard", P_("Sublevel discard"),
 		P_("Free sublevel arrays when their last element is removed"),
 		FALSE, G_PARAM_READWRITE));
 }
 
-static void scp_tree_store_init(ScpTreeStore *store)
+static volatile gsize scp_tree_store_type_id_volatile = 0;
+
+GType scp_tree_store_get_type(void)
 {
-	ScpTreeStorePrivate *priv;
+	if (g_once_init_enter(&scp_tree_store_type_id_volatile))
+	{
+		GType type = g_type_register_static_simple(G_TYPE_OBJECT,
+			g_intern_string("ScpTreeStore"), sizeof(ScpTreeStoreClass),
+			(GClassInitFunc) scp_tree_store_class_init, sizeof(ScpTreeStore), NULL, 0);
+		GInterfaceInfo iface_info = { (GInterfaceInitFunc) scp_tree_store_tree_model_init,
+			NULL, NULL };
+
+		g_type_add_interface_static(type, GTK_TYPE_TREE_MODEL, &iface_info);
+		iface_info.interface_init = (GInterfaceInitFunc) scp_tree_store_drag_source_init;
+		g_type_add_interface_static(type, GTK_TYPE_TREE_DRAG_SOURCE, &iface_info);
+		iface_info.interface_init = (GInterfaceInitFunc) scp_tree_store_drag_dest_init;
+		g_type_add_interface_static(type, GTK_TYPE_TREE_DRAG_DEST, &iface_info);
+		iface_info.interface_init = (GInterfaceInitFunc) scp_tree_store_sortable_init;
+		g_type_add_interface_static(type, GTK_TYPE_TREE_SORTABLE, &iface_info);
+		iface_info.interface_init = (GInterfaceInitFunc) scp_tree_store_buildable_init;
+		g_type_add_interface_static(type, GTK_TYPE_BUILDABLE, &iface_info);
+		g_once_init_leave(&scp_tree_store_type_id_volatile, type);
+	}
 
-	priv = G_TYPE_INSTANCE_GET_PRIVATE(store, SCP_TYPE_TREE_STORE, ScpTreeStorePrivate);
-	store->priv = priv;
-	while ((priv->stamp = g_random_int()) == 0);  /* we mark invalid iters with stamp 0 */
-	priv->root = g_new0(AElem, 1);
-	priv->roar = g_ptr_array_new();
-	scp_ptr_array_insert_val(priv->roar, 0, priv->root);
-	priv->headers = NULL;
-	priv->n_columns = 0;
-	priv->sort_column_id = GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID;
-	priv->sort_order = GTK_SORT_ASCENDING;
-	priv->sort_func = NULL;
-	priv->sublevels = TRUE;
-	priv->toplevel_reserved = 0;
-	priv->sublevel_reserved = 0;
-	priv->sublevel_discard = FALSE;
-	priv->columns_dirty = FALSE;
+	return scp_tree_store_type_id_volatile;
 }
 
-static void scp_tree_store_finalize(GObject *object)
+void scp_tree_store_register_dynamic(void)
 {
-	ScpTreeStore *store = SCP_TREE_STORE(object);
-	ScpTreeStorePrivate *priv = store->priv;
-
-	scp_free_array(store, priv->root->children);
-	g_free(priv->root);
-	g_ptr_array_free(priv->roar, TRUE);
+	GType type = g_type_from_name("ScpTreeStore");
 
-	if (priv->headers)
-		scp_tree_data_headers_free(priv->n_columns, priv->headers);
-
-	/* must chain up */
-	G_OBJECT_CLASS(scp_tree_store_parent_class)->finalize(object);
+	if (!type)
+	{
+		type = scp_tree_store_get_type();
+		g_type_class_unref(g_type_class_ref(type));  /* force class create */
+	}
+	else if (!scp_tree_store_type_id_volatile)
+	{
+		/* external registration, repair */
+		gpointer class = g_type_class_peek(type);
+		gpointer iface = g_type_interface_peek(class, GTK_TYPE_TREE_MODEL);
+
+		scp_tree_store_gobject_init((GObjectClass *) class);
+		scp_tree_store_tree_model_init((GtkTreeModelIface *) iface);
+		iface = g_type_interface_peek(class, GTK_TYPE_TREE_DRAG_SOURCE);
+		scp_tree_store_drag_source_init((GtkTreeDragSourceIface *) iface);
+		iface = g_type_interface_peek(class, GTK_TYPE_TREE_DRAG_DEST);
+		scp_tree_store_drag_dest_init((GtkTreeDragDestIface *) iface);
+		iface = g_type_interface_peek(class, GTK_TYPE_TREE_SORTABLE);
+		scp_tree_store_sortable_init((GtkTreeSortableIface *) iface);
+		iface = g_type_interface_peek(class, GTK_TYPE_BUILDABLE);
+		scp_tree_store_buildable_init((GtkBuildableIface *) iface);
+		scp_tree_store_type_id_volatile = type;
+	}
 }


Modified: scope/src/store/scptreestore.h
1 files changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -156,6 +156,7 @@ typedef gint (*ScpTreeStoreTraverseFunc)(ScpTreeStore *store, GtkTreeIter *iter,
 	gpointer gdata);
 gboolean scp_tree_store_traverse(ScpTreeStore *store, gboolean sublevels, GtkTreeIter *iter,
 	GtkTreeIter *parent, ScpTreeStoreTraverseFunc func, gpointer gdata);
+void scp_tree_store_register_dynamic(void);
 
 G_END_DECLS
 


Modified: scope/src/store/scptreestore.html
300 files changed, 57 insertions(+), 243 deletions(-)
===================================================================
@@ -4,9 +4,13 @@
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>ScpTreeStore</title>
-    <style type="text/css">
+<style type="text/css">
 	.tab { padding-left:2em; }
-    </style>
+	table { border-collapse:collapse; }
+	th, td { border: 1px solid black; }
+	.empty { border: 0px; }
+	th, td { padding: 0em 0.5em; }
+</style>
 </head>
 
 <body>
@@ -60,7 +64,8 @@
 ScpTreeStore *<a href="#scp_tree_store_newv">scp_tree_store_newv</a>(gboolean sublevels, gint
 n_columns, GType *types);<br>
 gboolean scp_tree_store_set_column_types(ScpTreeStore *store, gint n_columns, GType *types);<br>
-#define scp_tree_store_set_utf8_collate(store, utf8_collate)
+void <a href="#scp_tree_store_set_utf8_collate">scp_tree_store_set_utf8_collate</a>(ScpTreeStore
+*store, gint column, gboolean collate);<br>
 void scp_tree_store_set_valuesv(ScpTreeStore *store, GtkTreeIter *iter, gint *columns, GValue
 *values, gint n_values);<br>
 void scp_tree_store_set_value(ScpTreeStore *store, GtkTreeIter *iter, gint column, GValue
@@ -287,14 +292,15 @@
 collate);</b></p>
 
 <div>Normally, all stores compare strings with g_utf8_collate(), which is linguistically
-correct, but awfully slow. With the gtk+ stores, you can create a separate column with the
-string keys if needed, and write a small compare function that does g_strcmp0(). The side
-effects are that when a store is sorted by a non-standard function, setting the value of any
-column causes a check if the row is properly sorted, and ScpTreeStore's binary search can not
-be used.</div>
-<div class="tab">collate = <tt>TRUE</tt>: use g_utf8_collate() to compare strings, should only
-be used with string columns<br>
-collate = <tt>FALSE</tt>: use g_strcmp0() to compare strings, no side effects.</div>
+correct, but very slow. You can create a separate column with the string keys, of course, and
+write a small compare function that does g_strcmp0(), but the side effects are that in a store
+is sorted by a non-standard function, setting the value of any column causes a check if the
+row is properly sorted, and ScpTreeStore's binary search can not be used.</div>
+<div class="tab">collate = <tt>TRUE</tt>: use g_utf8_collate() to compare strings, only for
+string columns<br>
+collate = <tt>FALSE</tt>: use g_strcmp0() to compare strings, the above side effects mentioned
+above.
+</div>
 
 <hr>
 
@@ -336,6 +342,8 @@
 compare function is ignored, because it requires an iterator, not a value. For string columns,
 utf8_collate is taken into account.</p>
 
+<hr>
+
 <h3><a name="ScpTreeStoreTraverseFunc">ScpTreeStoreTraverseFunc()</a></h3>
 
 <p><b>gint ScpTreeStoreTraverseFunc(ScpTreeStore *store, GtkTreeIter *iter, gpointer gdata);
@@ -362,9 +370,25 @@
 
 <hr>
 
+<h3><a name="scp_tree_store_register_dynamic">scp_tree_store_register_dynamic()</a></h3>
+
+<p><b>scp_tree_store_register_dynamic(void);</b></p>
+
+<p>ScpTreeStore is written in a way that allows unloading the module which defines it,
+provided that:</p>
+
+<ul>
+<li>there are no stores in use</li>
+<li>no attempts to create a store while the module is unloaded</li>
+<li>this function is invoked once each time the module is (re)loaded, for example in it's
+startup code.</li>
+</ul>
+
+<hr>
+
 <h3><a name="properties">Properties</a></h3>
 
-<p>"sublevels" (gboolean, read/construct only write) - whether the store supports
+<p>"sublevels" (gboolean, read/construct) - whether the store supports
 sublevels.</p>
 
 <p>"toplevel-reserved" (gint, read/write) - number of pointers to preallocate for
@@ -412,264 +436,54 @@
 reordered?]</p>
 
 <p>When the top-level rows are being reordered, such iter may not be valid, because it must
-point above the top. Both GtkTreeStore and ScpTreeStore pass a pseudo-valid iter which is
-suitable for a few operations, but you should not rely on that and check for path depth =
-<tt>0</tt> instead.</p>
+point above the top. GtkTreeStore pass a pseudo-valid iter which is suitable for a few
+operations, and so does ScpTreeStore, but you should not rely on that and check for path
+depth = <tt>0</tt> instead.</p>
 
 <hr>
 
 <h3><a name="speed">Speed</a></h3>
 
-<table>
-<tr><th>Unsorted store</th><th>Row count</th><th>GtkTreeStore</th>
-<th>ScpTreeStore</th><th>Times</th></tr>
-
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level set</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level remove</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>25</td><td>0.000</td><td>0.000</td><td>25</td></tr>
-<tr><td>top-level iter search string</td><td>25</td><td>0.003</td><td>0.002</td><td>25</td></tr>
-<tr><td>top-level linear search double</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
-<tr><td>top-level linear search string</td><td>25</td><td>n/a</td><td>0.001</td><td>25</td></tr>
-<tr><td>both levels model foreach</td><td>25</td><td>0.000</td><td>0.000</td><td>25</td></tr>
-<tr><td>both levels store traverse</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
-<tr><td>top-level quick sort double</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>25</td><td>0.001</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 insert_with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>25</td><td>0.001</td><td>0.001</td><td></td></tr>
-
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level set</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
-<tr><td>top-level remove</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>100</td><td>0.006</td><td>0.000</td><td>100</td></tr>
-<tr><td>top-level iter search string</td><td>100</td><td>0.034</td><td>0.027</td><td>100</td></tr>
-<tr><td>top-level linear search double</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr>
-<tr><td>top-level linear search string</td><td>100</td><td>n/a</td><td>0.015</td><td>100</td></tr>
-<tr><td>both levels model foreach</td><td>100</td><td>0.003</td><td>0.003</td><td>100</td></tr>
-<tr><td>both levels store traverse</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr>
-<tr><td>top-level quick sort double</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>100</td><td>0.003</td><td>0.002</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 insert with values</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>100</td><td>0.005</td><td>0.004</td><td></td></tr>
-
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
-<tr><td>top-level set</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
-<tr><td>top-level remove</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>250</td><td>0.031</td><td>0.003</td><td>250</td></tr>
-<tr><td>top-level iter search string</td><td>250</td><td>0.224</td><td>0.183</td><td>250</td></tr>
-<tr><td>top-level linear search double</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr>
-<tr><td>top-level linear search string</td><td>250</td><td>n/a</td><td>0.109</td><td>250</td></tr>
-<tr><td>both levels model foreach</td><td>250</td><td>0.018</td><td>0.018</td><td>250</td></tr>
-<tr><td>both levels store traverse</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr>
-<tr><td>top-level quick sort double</td><td>250</td><td>0.001</td><td>0.000</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>250</td><td>0.009</td><td>0.008</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr>
-<tr><td>sublevel 1 insert with values</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>250</td><td>0.002</td><td>0.000</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>250</td><td>0.015</td><td>0.012</td><td></td></tr>
-
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr>
-<tr><td>top-level set</td><td>500</td><td>0.003</td><td>0.002</td><td></td></tr>
-<tr><td>top-level remove</td><td>500</td><td>0.002</td><td>0.001</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>500</td><td>0.003</td><td>0.002</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>500</td><td>0.131</td><td>0.010</td><td>500</td></tr>
-<tr><td>top-level iter search string</td><td>500</td><td>0.909</td><td>0.722</td><td>500</td></tr>
-<tr><td>top-level linear search double</td><td>500</td><td>n/a</td><td>0.005</td><td>500</td></tr>
-<tr><td>top-level linear search string</td><td>500</td><td>n/a</td><td>0.443</td><td>500</td></tr>
-<tr><td>both levels model foreach</td><td>500</td><td>0.077</td><td>0.076</td><td>500</td></tr>
-<tr><td>both levels store traverse</td><td>500</td><td>n/a</td><td>0.003</td><td>500</td></tr>
-<tr><td>top-level quick sort double</td><td>500</td><td>0.003</td><td>0.001</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>500</td><td>0.022</td><td>0.018</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>500</td><td>0.004</td><td>0.002</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr>
-<tr><td>sublevel 1 insert with values</td><td>500</td><td>0.004</td><td>0.003</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>500</td><td>0.005</td><td>0.001</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>500</td><td>0.034</td><td>0.028</td><td></td></tr>
-
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>1000</td><td>0.004</td><td>0.003</td><td></td></tr>
-<tr><td>top-level set</td><td>1000</td><td>0.007</td><td>0.003</td><td></td></tr>
-<tr><td>top-level remove</td><td>1000</td><td>0.004</td><td>0.003</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>1000</td><td>0.007</td><td>0.004</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>1000</td><td>0.052</td><td>0.004</td><td>100</td></tr>
-<tr><td>top-level iter search string</td><td>1000</td><td>0.370</td><td>0.273</td><td>100</td></tr>
-<tr><td>top-level linear search double</td><td>1000</td><td>n/a</td><td>0.002</td><td>100</td></tr>
-<tr><td>top-level linear search string</td><td>1000</td><td>n/a</td><td>0.182</td><td>100</td></tr>
-<tr><td>both levels model foreach</td><td>1000</td><td>0.033</td><td>0.030</td><td>100</td></tr>
-<tr><td>both levels store traverse</td><td>1000</td><td>n/a</td><td>0.001</td><td>100</td></tr>
-<tr><td>top-level quick sort double</td><td>1000</td><td>0.007</td><td>0.002</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>1000</td><td>0.050</td><td>0.040</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>1000</td><td>0.006</td><td>0.004</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>1000</td><td>0.009</td><td>0.005</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>1000</td><td>0.006</td><td>0.004</td><td></td></tr>
-<tr><td>sublevel 1 insert with values</td><td>1000</td><td>0.009</td><td>0.006</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>1000</td><td>0.011</td><td>0.002</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>1000</td><td>0.078</td><td>0.062</td><td></td></tr>
-
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>2500</td><td>0.017</td><td>0.008</td><td></td></tr>
-<tr><td>top-level set</td><td>2500</td><td>0.026</td><td>0.009</td><td></td></tr>
-<tr><td>top-level remove</td><td>2500</td><td>0.019</td><td>0.008</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>2500</td><td>0.026</td><td>0.012</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>2500</td><td>0.340</td><td>0.028</td><td>250</td></tr>
-<tr><td>top-level iter search string</td><td>2500</td><td>2.273</td><td>1.859</td><td>250</td></tr>
-<tr><td>top-level linear search double</td><td>2500</td><td>n/a</td><td>0.015</td><td>250</td></tr>
-<tr><td>top-level linear search string</td><td>2500</td><td>n/a</td><td>1.137</td><td>250</td></tr>
-<tr><td>both levels model foreach</td><td>2500</td><td>0.182</td><td>0.188</td><td>250</td></tr>
-<tr><td>both levels store traverse</td><td>2500</td><td>n/a</td><td>0.009</td><td>250</td></tr>
-<tr><td>top-level quick sort double</td><td>2500</td><td>0.021</td><td>0.004</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>2500</td><td>0.146</td><td>0.117</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>2500</td><td>0.035</td><td>0.014</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>2500</td><td>0.048</td><td>0.014</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>2500</td><td>0.038</td><td>0.013</td><td></td></tr>
-<tr><td>sublevel 1 insert with values</td><td>2500</td><td>0.046</td><td>0.017</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>2500</td><td>0.033</td><td>0.007</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>2500</td><td>0.230</td><td>0.181</td><td></td></tr>
-
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>5000</td><td>0.084</td><td>0.019</td><td></td></tr>
-<tr><td>top-level set</td><td>5000</td><td>0.107</td><td>0.017</td><td></td></tr>
-<tr><td>top-level remove</td><td>5000</td><td>0.089</td><td>0.018</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>5000</td><td>0.103</td><td>0.025</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>5000</td><td>1.271</td><td>0.112</td><td>500</td></tr>
-<tr><td>top-level iter search string</td><td>5000</td><td>8.775</td><td>7.787</td><td>500</td></tr>
-<tr><td>top-level linear search double</td><td>5000</td><td>n/a</td><td>0.060</td><td>500</td></tr>
-<tr><td>top-level linear search string</td><td>5000</td><td>n/a</td><td>4.351</td><td>500</td></tr>
-<tr><td>both levels model foreach</td><td>5000</td><td>0.741</td><td>0.754</td><td>500</td></tr>
-<tr><td>both levels store traverse</td><td>5000</td><td>n/a</td><td>0.042</td><td>500</td></tr>
-<tr><td>top-level quick sort double</td><td>5000</td><td>0.046</td><td>0.010</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>5000</td><td>0.325</td><td>0.264</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>5000</td><td>0.168</td><td>0.040</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>5000</td><td>0.201</td><td>0.038</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>5000</td><td>0.184</td><td>0.038</td><td></td></tr>
-<tr><td>sublevel 1 insert with values</td><td>5000</td><td>0.199</td><td>0.046</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>5000</td><td>0.073</td><td>0.015</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>5000</td><td>0.508</td><td>0.405</td><td></td></tr>
+<p>An unsorted ScpTreeStore is faster than GtkTreeStore, but the difference is not big (20%
+on average, depending on the operation and number of elements), and not significant (< 0.5+
+seconds) for stores with less than 10000 elements. Normally, inserting into and removing from
+a list is faster than array, but all store operations must emit a signal, containing the row
+path (numeric index), which negates this advantage.</p>
 
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>top-level insert</td><td>10000</td><td>0.410</td><td>0.049</td><td></td></tr>
-<tr><td>top-level set</td><td>10000</td><td>0.465</td><td>0.035</td><td></td></tr>
-<tr><td>top-level remove</td><td>10000</td><td>0.430</td><td>0.045</td><td></td></tr>
-<tr><td>top-level insert with values</td><td>10000</td><td>0.461</td><td>0.059</td><td></td></tr>
-<tr><td>top-level iter search double</td><td>10000</td><td>7.434</td><td>0.509</td><td>1000</td></tr>
-<tr><td>top-level iter search string</td><td>10000</td><td>37.555</td><td>31.020</td><td>1000</td></tr>
-<tr><td>top-level linear search double</td><td>10000</td><td>n/a</td><td>0.304</td><td>1000</td></tr>
-<tr><td>top-level linear search string</td><td>10000</td><td>n/a</td><td>18.896</td><td>1000</td></tr>
-<tr><td>both levels model foreach</td><td>10000</td><td>2.969</td><td>3.136</td><td>1000</td></tr>
-<tr><td>both levels store traverse</td><td>10000</td><td>n/a</td><td>0.238</td><td>1000</td></tr>
-<tr><td>top-level quick sort double</td><td>10000</td><td>0.112</td><td>0.022</td><td></td></tr>
-<tr><td>top-level quick sort string</td><td>10000</td><td>0.720</td><td>0.580</td><td></td></tr>
-<tr><td>sublevel 1 insert</td><td>10000</td><td>1.152</td><td>0.132</td><td></td></tr>
-<tr><td>sublevel 1 set</td><td>10000</td><td>1.730</td><td>0.116</td><td></td></tr>
-<tr><td>sublevel 1 remove</td><td>10000</td><td>1.364</td><td>0.128</td><td></td></tr>
-<tr><td>sublevel 1 insert with values</td><td>10000</td><td>1.427</td><td>0.146</td><td></td></tr>
-<tr><td>sublevel 1 quick sort double</td><td>10000</td><td>0.170</td><td>0.034</td><td></td></tr>
-<tr><td>sublevel 1 quick sort string</td><td>10000</td><td>1.114</td><td>0.893</td><td></td></tr>
+<p>The sorted gtk+ stores are slow, since they are based on lists, and sorting by a string
+with utf8 collation makes them even slower.</p>
 
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<table>
 <tr><th>Store sorted by double</th><th>Row count</th><th>GtkTreeStore</th>
 <th>ScpTreeStore</th><th>Times</th></tr>
 <tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>25</td><td>0.003</td><td>0.000</td><td></td></tr>
-<tr><td>pre/append with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr>
-<tr><td>binary search</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>100</td><td>0.004</td><td>0.001</td><td></td></tr>
-<tr><td>pre/append with values</td><td>100</td><td>0.003</td><td>0.000</td><td></td></tr>
-<tr><td>binary search</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
 <tr><td>pre/apppend + set</td><td>250</td><td>0.019</td><td>0.003</td><td></td></tr>
 <tr><td>pre/append with values</td><td>250</td><td>0.015</td><td>0.001</td><td></td></tr>
 <tr><td>binary search</td><td>250</td><td>n/a</td><td>0.000</td><td>250</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>500</td><td>0.068</td><td>0.007</td><td></td></tr>
-<tr><td>pre/append with values</td><td>500</td><td>0.054</td><td>0.003</td><td></td></tr>
-<tr><td>binary search</td><td>500</td><td>n/a</td><td>0.000</td><td>500</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>1000</td><td>0.225</td><td>0.015</td><td></td></tr>
-<tr><td>pre/append with values</td><td>1000</td><td>0.203</td><td>0.006</td><td></td></tr>
-<tr><td>binary search</td><td>1000</td><td>n/a</td><td>0.001</td><td>1000</td></tr>
+<tr><td>unsorted store search</td><td>250</td><td>0.031</td><td>0.003</td><td>250</td></tr>
 <tr><td> </td><td></td><td></td><td></td><td></td></tr>
 <tr><td>pre/apppend + set</td><td>2500</td><td>1.474</td><td>0.044</td><td></td></tr>
 <tr><td>pre/append with values</td><td>2500</td><td>1.324</td><td>0.015</td><td></td></tr>
 <tr><td>binary search</td><td>2500</td><td>n/a</td><td>0.002</td><td>2500</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>5000</td><td>6.432</td><td>0.115</td><td></td></tr>
-<tr><td>pre/append with values</td><td>5000</td><td>5.624</td><td>0.035</td><td></td></tr>
-<tr><td>binary search</td><td>5000</td><td>n/a</td><td>0.004</td><td>5000</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>10000</td><td>26.967</td><td>0.335</td><td></td></tr>
-<tr><td>pre/append with values</td><td>10000</td><td>23.803</td><td>0.081</td><td></td></tr>
-<tr><td>binary search</td><td>10000</td><td>n/a</td><td>0.009</td><td>10000</td></tr>
+<tr><td>unsorted store search</td><td>2500</td><td>0.340</td><td>0.028</td><td><i>250</i></td></tr>
 
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
+<tr><td colspan="5" class="empty"> </td></tr>
 <tr><th>Store sorted by string</th><th>Row count</th><th>GtkTreeStore</th>
 <th>ScpTreeStore</th><th>Times</th></tr>
 <tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>25</td><td>0.003</td><td>0.001</td><td></td></tr>
-<tr><td>pre/append with values</td><td>25</td><td>0.001</td><td>0.001</td><td></td></tr>
-<tr><td>binary search</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>100</td><td>0.014</td><td>0.005</td><td></td></tr>
-<tr><td>pre/append with values</td><td>100</td><td>0.014</td><td>0.003</td><td></td></tr>
-<tr><td>binary search</td><td>100</td><td>n/a</td><td>0.002</td><td>100</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
 <tr><td>pre/apppend + set</td><td>250</td><td>0.092</td><td>0.015</td><td></td></tr>
 <tr><td>pre/append with values</td><td>250</td><td>0.093</td><td>0.009</td><td></td></tr>
 <tr><td>binary search</td><td>250</td><td>n/a</td><td>0.006</td><td>250</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>500</td><td>0.366</td><td>0.034</td><td></td></tr>
-<tr><td>pre/append with values</td><td>500</td><td>0.343</td><td>0.021</td><td></td></tr>
-<tr><td>binary search</td><td>500</td><td>n/a</td><td>0.012</td><td>500</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>1000</td><td>1.415</td><td>0.077</td><td></td></tr>
-<tr><td>pre/append with values</td><td>1000</td><td>1.444</td><td>0.047</td><td></td></tr>
-<tr><td>binary search</td><td>1000</td><td>n/a</td><td>0.028</td><td>1000</td></tr>
+<tr><td>unsorted store search</td><td>250</td><td>0.224</td><td>0.183</td><td>250</td></tr>
 <tr><td> </td><td></td><td></td><td></td><td></td></tr>
 <tr><td>pre/apppend + set</td><td>2500</td><td>9.032</td><td>0.229</td><td></td></tr>
 <tr><td>pre/append with values</td><td>2500</td><td>9.061</td><td>0.134</td><td></td></tr>
 <tr><td>binary search</td><td>2500</td><td>n/a</td><td>0.080</td><td>2500</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>5000</td><td>36.648</td><td>0.521</td><td></td></tr>
-<tr><td>pre/append with values</td><td>5000</td><td>38.045</td><td>0.296</td><td></td></tr>
-<tr><td>binary search</td><td>5000</td><td>n/a</td><td>0.177</td><td>5000</td></tr>
-<tr><td> </td><td></td><td></td><td></td><td></td></tr>
-<tr><td>pre/apppend + set</td><td>10000</td><td>slow</td><td>1.225</td><td></td></tr>
-<tr><td>pre/append with values</td><td>10000</td><td>slow</td><td>0.654</td><td></td></tr>
-<tr><td>binary search</td><td>10000</td><td>n/a</td><td>0.385</td><td>10000</td></tr>
-
+<tr><td>unsorted store search</td><td>2500</td><td>2.273</td><td>1.859</td><td><i>250</i></td></tr>
 </table>
 
-<p>pre/append = prepend for GtkTreeStore (faster than append) and append for ScpTreeStore
-(faster than prepend)<br>
-all defensive checks enabled, all string tests with utf8 collation</p>
-
-<p>The difference is easy to explain. First, GtkTreeStore often converts values between their
-internal store presentation and GValue, duplicating strings and referencing objects. Second,
-binary vs. linear search. Third, invoking the GtkTreeModel implementation functions directly
-makes a difference for a lot of calls. Fourth, GtkTreeStore uses lists to keep the row values
-and column sort headers, but the columns are arways referenced by index. By itself, inserting
-into and removing from a list should be faster than the same array operations. But the store
-operations must emit a signal, containing the row path (index), which negates this advantage.
-</p>
+<p>The full speed test is <a href="fullspeed.html">here</a>. In general, a sorted ScpTreeStore
+can be used as a normal data structure, which is not the case with GtkTree/ListStore.</p>
 
 <hr>
 
@@ -689,10 +503,10 @@
 
 <p><b>GtkTreeStore, Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford</b></p>
 
-<p>ScpTreeStore was initially written for the Scope plugin of Geany light IDE, which relies
-heavily on stores.</p>
+<p>ScpTreeStore was written for the Scope plugin of Geany light IDE, which relies heavily on
+stores.</p>
 
-<p><b>ScpTreeStore 0.84, Copyright (C) 2013 Dimitar Toshkov Zhekov</b></p>
+<p><b>ScpTreeStore 0.85, Copyright (C) 2013 Dimitar Toshkov Zhekov</b></p>
 
 <p>ScpTreeStore is distributed 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


Modified: scope/src/thread.c
13 files changed, 4 insertions(+), 9 deletions(-)
===================================================================
@@ -172,10 +172,10 @@ static void auto_select_thread(void)
 	}
 }
 
-guint thread_count;
-const char *thread_id;
-ThreadState thread_state;
-guint thread_prompt;
+guint thread_count = 0;
+const char *thread_id = NULL;
+ThreadState thread_state = THREAD_BLANK;
+guint thread_prompt = 0;
 
 const char *thread_group_id(void)
 {
@@ -876,11 +876,6 @@ void thread_init(void)
 	GtkTreeView *tree = view_create("thread_view", &store, &selection);
 	GtkWidget *menu = menu_select("thread_menu", &thread_menu_info, selection);
 
-	thread_count = 0;
-	thread_id = NULL;
-	thread_state = THREAD_BLANK;
-	thread_prompt = 0;
-
 	view_set_sort_func(store, THREAD_ID, store_gint_compare);
 	view_set_sort_func(store, THREAD_FILE, store_seek_compare);
 	view_set_line_data_func("thread_line_column", "thread_line", THREAD_LINE);


Modified: scope/src/tooltip.c
20 files changed, 6 insertions(+), 14 deletions(-)
===================================================================
@@ -48,9 +48,9 @@ static void tooltip_trigger(void)
 	}
 }
 
-static gchar *output;
-static gint last_pos;
-static gint peek_pos;
+static gchar *output = NULL;
+static gint last_pos = -1;
+static gint peek_pos = -1;
 static gboolean show;
 
 static void tooltip_set(gchar *text)
@@ -69,7 +69,7 @@ static void tooltip_set(gchar *text)
 	}
 }
 
-static gint scid_gen;
+static gint scid_gen = 0;
 
 void on_tooltip_error(GArray *nodes)
 {
@@ -86,7 +86,7 @@ void on_tooltip_error(GArray *nodes)
 	}
 }
 
-static char *input;
+static char *input = NULL;
 
 void on_tooltip_value(GArray *nodes)
 {
@@ -97,7 +97,7 @@ void on_tooltip_value(GArray *nodes)
 	}
 }
 
-static guint query_id;
+static guint query_id = 0;
 
 static gboolean tooltip_launch(gpointer gdata)
 {
@@ -200,14 +200,6 @@ gboolean tooltip_update(void)
 	return TRUE;
 }
 
-void tooltip_init(void)
-{
-	output = NULL;
-	tooltip_clear();
-	input = NULL;
-	query_id = 0;
-}
-
 void tooltip_finalize(void)
 {
 	g_free(output);


Modified: scope/src/tooltip.h
1 files changed, 0 insertions(+), 1 deletions(-)
===================================================================
@@ -28,7 +28,6 @@
 void tooltip_clear(void);
 gboolean tooltip_update(void);
 
-void tooltip_init(void);
 void tooltip_finalize(void);
 
 #define TOOLTIP_H 1


Modified: scope/src/views.c
27 files changed, 12 insertions(+), 15 deletions(-)
===================================================================
@@ -50,7 +50,7 @@
 	{ FALSE, VC_FRAME, watches_clear,   watches_update,   FALSE, DS_VARIABLE },
 	{ FALSE, VC_DATA,  memory_clear,    memory_update,    FALSE, DS_VARIABLE },
 	{ FALSE, VC_NONE,  NULL,            dc_update,        FALSE, DS_DEBUG },
-	{ FALSE, VC_FRAME, inspects_clear,  inspects_update,  FALSE, DS_DEBUG },
+	{ FALSE, VC_FRAME, inspects_clear,  inspects_update,  FALSE, DS_VARIABLE },
 	{ FALSE, VC_FRAME, registers_clear, registers_update, TRUE,  DS_DEBUG },
 	{ FALSE, VC_DATA,  tooltip_clear,   tooltip_update,   FALSE, DS_SENDABLE },
 	{ FALSE, VC_NONE,  menu_clear,      NULL,             FALSE, 0 }
@@ -114,7 +114,11 @@ void views_context_dirty(DebugState state, gboolean frame_only)
 	}
 }
 
-static ViewIndex view_current;
+#ifdef G_OS_UNIX
+static ViewIndex view_current = VIEW_TERMINAL;
+#else
+static ViewIndex view_current = VIEW_THREADS;
+#endif
 
 void views_clear(void)
 {
@@ -579,18 +583,18 @@ gboolean view_command_active(void)
 	return gtk_widget_get_visible(command_dialog);
 }
 
-static DebugState last_views_state;
-
 void views_update_state(DebugState state)
 {
-	if (state != last_views_state)
+	static DebugState last_state = 0;
+
+	if (state != last_state)
 	{
 		if (gtk_widget_get_visible(command_dialog))
 			command_line_update_state(state);
 		locals_update_state(state);
 		watches_update_state(state);
 		inspects_update_state(state);
-		last_views_state = state;
+		last_state = state;
 	}
 }
 
@@ -604,15 +608,8 @@ static void on_geany_sidebar_switch_page(G_GNUC_UNUSED GtkNotebook *notebook,
 
 void views_init(void)
 {
-#ifdef G_OS_UNIX
-	view_current = VIEW_TERMINAL;
-#else
-	view_current = VIEW_THREADS;
-#endif
-	last_views_state = 0;
-
-	if (!pref_var_update_bug)
-		views[VIEW_INSPECT].state = DS_VARIABLE;
+	if (pref_var_update_bug)
+		views[VIEW_INSPECT].state = DS_DEBUG;
 
 	command_dialog = dialog_connect("command_dialog");
 	command_view = get_widget("command_view");



--------------
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