[geany/geany] 1d64d5: Replace dynamic exports with codegen for GtkBuilder callbacks

Matthew Brush git-noreply at xxxxx
Fri Apr 10 15:07:10 UTC 2015


Branch:      refs/heads/master
Author:      Matthew Brush <matt at geany.org>
Committer:   Thomas Martitz <kugel at rockbox.org>
Date:        Tue, 10 Mar 2015 22:10:06 UTC
Commit:      1d64d5211fc7c660d9facbc5c927bbce32029863
             https://github.com/geany/geany/commit/1d64d5211fc7c660d9facbc5c927bbce32029863

Log Message:
-----------
Replace dynamic exports with codegen for GtkBuilder callbacks

This prevents having to export those callbacks and put them in the
global namespace. Also, use inline shell script in Makefile.am instead
of a Python script which should be more portable (by default) and gets
rid of the helper script.


Modified Paths:
--------------
    m4/geany-lib.m4
    scripts/dynamicsymbols.py
    src/Makefile.am
    src/callbacks.c
    src/callbacks.h
    src/dynamicsymbols.list
    src/signalconn.c.in
    src/ui_utils.c

Modified: m4/geany-lib.m4
23 lines changed, 6 insertions(+), 17 deletions(-)
===================================================================
@@ -24,25 +24,14 @@ dnl `__attribute__((visibility(...)))` extension and use it if so.
 		])
 	CFLAGS="${libgeany_backup_cflags}"
 
-dnl Try and see if we can use our list of dynamically exported symbols with
-dnl the linker and use it if so.
-	AC_MSG_CHECKING([whether linker supports --dynamic-list])
-	libgeany_backup_ldflags=$LDFLAGS
-	LDFLAGS=-Wl,--dynamic-list="${srcdir}/src/dynamicsymbols.list"
-	AC_LINK_IFELSE([
-			AC_LANG_PROGRAM([], [])
-		], [
-			LIBGEANY_LIBS="-Wl,--dynamic-list=\"\$(top_srcdir)/src/dynamicsymbols.list\""
-			AC_MSG_RESULT([yes])
-		], [
-			LIBGEANY_LIBS=""
-			AC_MSG_RESULT([no])
-		])
-	LDFLAGS="${libgeany_backup_ldflags}"
-
-	LIBGEANY_LIBS="${LIBGEANY_LIBS} -version-info ${libgeany_current}:${libgeany_revision}:${libgeany_age}"
+	LIBGEANY_LIBS="-version-info ${libgeany_current}:${libgeany_revision}:${libgeany_age}"
 
 	AC_SUBST([LIBGEANY_CFLAGS])
 	AC_SUBST([LIBGEANY_LIBS])
 
+dnl Check for utilities needed to do codegen
+	AC_PATH_PROG([SORT], [sort], [
+		AC_MSG_ERROR([The 'sort' utility is required, is it installed?])])
+	AC_PATH_PROG([UNIQ], [uniq], [
+		AC_MSG_ERROR([The 'uniq' utility is required, is it installed?])])
 ])


Modified: scripts/dynamicsymbols.py
73 lines changed, 0 insertions(+), 73 deletions(-)
===================================================================
@@ -1,73 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Script to parse GtkBuilder XML file for signal handler references and list
-them in a linker file for which symbols to dynamically export.
-"""
-
-import optparse
-import os
-import re
-import sys
-from xml.etree import ElementTree as ET
-
-def find_handlers(xml_filename, excludes=[]):
-    def is_excluded(name, excludes):
-        for exclude in excludes:
-            m = re.match(exclude, name)
-            if m:
-                return True
-        return False
-
-    tree = ET.parse(xml_filename)
-    root = tree.getroot()
-    handlers = []
-    signals = root.findall(".//signal")
-
-    for signal in signals:
-        handler = signal.attrib["handler"]
-        if not is_excluded(handler, excludes):
-            handlers.append(handler)
-
-    return sorted(handlers)
-
-def write_dynamic_list(handlers, output_file):
-    output_file.write("""\
-/* This file was auto-generated by the `%s' script, do not edit. */
-{
-""" % os.path.basename(__file__))
-    for handler in handlers:
-        output_file.write("\t%s;\n" % handler)
-    output_file.write("};\n")
-
-def main(args):
-    p = optparse.OptionParser(usage="%prog [-o FILE] XMLFILE")
-    p.add_option("-o", "--output", metavar="FILE", dest="output_file",
-        default="-", help="write the output to this file (default `-' for stdin)")
-
-    opts, args = p.parse_args(args)
-
-    output_file = None
-    try:
-        if opts.output_file == "-":
-            output_file = sys.stdout
-        else:
-            output_file = open(opts.output_file, 'w')
-
-        args = args[1:]
-        if len(args) == 0:
-            p.error("invalid XMLFILE argument, expecting a filename, got none")
-        elif len(args) > 1:
-            p.error("too many XMLFILE arguments, expecting a single filename")
-
-        handlers = find_handlers(args[0], ["gtk_.+"])
-        write_dynamic_list(handlers, output_file)
-
-    finally:
-        if output_file is not None and output_file is not sys.stdout:
-            output_file.close()
-
-    return 0
-
-if __name__ == "__main__":
-    sys.exit(main(sys.argv))


Modified: src/Makefile.am
24 lines changed, 17 insertions(+), 7 deletions(-)
===================================================================
@@ -11,7 +11,7 @@ EXTRA_DIST = \
 	pluginprivate.h \
 	projectprivate.h \
 	makefile.win32 \
-	$(top_srcdir)/src/dynamicsymbols.list
+	$(srcdir)/signalconn.c.in
 
 bin_PROGRAMS = geany
 lib_LTLIBRARIES = libgeany.la
@@ -173,10 +173,20 @@ AM_CFLAGS = -DGEANY_DATADIR=\""$(datadir)"\" \
 
 clean-local:
 
-# Helper rule to rebuild the dynamicsymbols.list file when handlers are
-# added to data/geany.glade. Run `make dynamic-symbols' from the src builddir.
-$(top_srcdir)/src/dynamicsymbols.list: $(top_srcdir)/data/geany.glade
-	-python $(top_srcdir)/scripts/dynamicsymbols.py -o $@ $(top_srcdir)/data/geany.glade
-dynamic-symbols: $(top_srcdir)/src/dynamicsymbols.list
-
 endif
+
+callbacks.c: signalconn.c
+
+glade_file=$(top_srcdir)/data/geany.glade
+template_file=$(srcdir)/signalconn.c.in
+
+signalconn.c: $(glade_file) $(template_file)
+	$(AM_V_GEN)( \
+		echo '/* This file is auto-generated, do not edit. */' && \
+		$(SED) -n '/@callback_map@/q;p' "$(template_file)" && \
+		$(SED) -n 's/^.*handler="\([^"]\+\)".*$$/\tg_hash_table_insert(hash, "\1", G_CALLBACK(\1));/p' "$(glade_file)" \
+			| $(SORT) | $(UNIQ) && \
+		$(SED) -n '/@callback_map@/{:l;n;p;b l}' "$(template_file)" \
+	) > $@ || { $(RM) $@ && exit 1; }
+
+CLEANFILES = signalconn.c


Modified: src/callbacks.c
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -1988,3 +1988,5 @@ GEANY_EXPORT_SYMBOL void on_detect_width_from_file_activate(GtkMenuItem *menuite
 		ui_document_show_hide(doc);
 	}
 }
+
+#include "signalconn.c"


Modified: src/callbacks.h
3 lines changed, 3 insertions(+), 0 deletions(-)
===================================================================
@@ -26,6 +26,9 @@
 
 G_BEGIN_DECLS
 
+/* Defined in auto-generated code in signalconn.c */
+void callbacks_connect(GtkBuilder *builder);
+
 extern gboolean	ignore_callback;
 
 void on_new1_activate(GtkMenuItem *menuitem, gpointer user_data);


Modified: src/dynamicsymbols.list
161 lines changed, 0 insertions(+), 161 deletions(-)
===================================================================
@@ -1,161 +0,0 @@
-/* This file was auto-generated by the `dynamicsymbols.py' script, do not edit. */
-{
-	on_button_customize_toolbar_clicked;
-	on_change_font1_activate;
-	on_clone1_activate;
-	on_close1_activate;
-	on_close_all1_activate;
-	on_close_other_documents1_activate;
-	on_comments_bsd_activate;
-	on_comments_changelog_activate;
-	on_comments_changelog_activate;
-	on_comments_fileheader_activate;
-	on_comments_fileheader_activate;
-	on_comments_function_activate;
-	on_comments_function_activate;
-	on_comments_gpl_activate;
-	on_comments_multiline_activate;
-	on_context_action1_activate;
-	on_copy1_activate;
-	on_copy1_activate;
-	on_copy_current_lines1_activate;
-	on_count_words1_activate;
-	on_cr_activate;
-	on_crlf_activate;
-	on_customize_toolbar1_activate;
-	on_cut1_activate;
-	on_cut1_activate;
-	on_cut_current_lines1_activate;
-	on_debug_messages1_activate;
-	on_delete1_activate;
-	on_delete1_activate;
-	on_delete_current_lines1_activate;
-	on_detect_type_from_file_activate;
-	on_detect_width_from_file_activate;
-	on_duplicate_line_or_selection1_activate;
-	on_edit1_activate;
-	on_escape_key_press_event;
-	on_file1_activate;
-	on_file_properties_activate;
-	on_find1_activate;
-	on_find_document_usage1_activate;
-	on_find_document_usage1_activate;
-	on_find_in_files1_activate;
-	on_find_next1_activate;
-	on_find_nextsel1_activate;
-	on_find_previous1_activate;
-	on_find_prevsel1_activate;
-	on_find_usage1_activate;
-	on_find_usage1_activate;
-	on_fullscreen1_toggled;
-	on_go_to_line_activate;
-	on_go_to_next_marker1_activate;
-	on_go_to_previous_marker1_activate;
-	on_goto_tag_declaration1;
-	on_goto_tag_definition1;
-	on_goto_tag_definition1;
-	on_help1_activate;
-	on_help_menu_item_bug_report_activate;
-	on_help_menu_item_donate_activate;
-	on_help_menu_item_wiki_activate;
-	on_help_shortcuts1_activate;
-	on_hide_toolbar1_activate;
-	on_indent_width_activate;
-	on_indent_width_activate;
-	on_indent_width_activate;
-	on_indent_width_activate;
-	on_indent_width_activate;
-	on_indent_width_activate;
-	on_indent_width_activate;
-	on_indent_width_activate;
-	on_info1_activate;
-	on_insert_alternative_white_space1_activate;
-	on_insert_alternative_white_space1_activate;
-	on_lf_activate;
-	on_line_breaking1_activate;
-	on_line_wrapping1_toggled;
-	on_load_tags1_activate;
-	on_mark_all1_activate;
-	on_markers_margin1_toggled;
-	on_menu_color_schemes_activate;
-	on_menu_comment_line1_activate;
-	on_menu_comments_bsd_activate;
-	on_menu_comments_gpl_activate;
-	on_menu_comments_multiline_activate;
-	on_menu_decrease_indent1_activate;
-	on_menu_fold_all1_activate;
-	on_menu_increase_indent1_activate;
-	on_menu_open_selected_file1_activate;
-	on_menu_open_selected_file1_activate;
-	on_menu_project1_activate;
-	on_menu_reload_configuration1_activate;
-	on_menu_remove_indicators1_activate;
-	on_menu_select_all1_activate;
-	on_menu_select_all1_activate;
-	on_menu_show_indentation_guides1_toggled;
-	on_menu_show_line_endings1_toggled;
-	on_menu_show_sidebar1_toggled;
-	on_menu_show_white_space1_toggled;
-	on_menu_toggle_all_additional_widgets1_activate;
-	on_menu_toggle_line_commentation1_activate;
-	on_menu_uncomment_line1_activate;
-	on_menu_unfold_all1_activate;
-	on_menu_write_unicode_bom1_toggled;
-	on_motion_event;
-	on_move_lines_down1_activate;
-	on_move_lines_up1_activate;
-	on_new1_activate;
-	on_next_message1_activate;
-	on_normal_size1_activate;
-	on_notebook1_switch_page_after;
-	on_open1_activate;
-	on_page_setup1_activate;
-	on_paste1_activate;
-	on_paste1_activate;
-	on_plugin_preferences1_activate;
-	on_preferences1_activate;
-	on_previous_message1_activate;
-	on_print1_activate;
-	on_project_close1_activate;
-	on_project_new1_activate;
-	on_project_open1_activate;
-	on_project_properties1_activate;
-	on_quit1_activate;
-	on_redo1_activate;
-	on_redo1_activate;
-	on_reflow_lines_block1_activate;
-	on_remove_markers1_activate;
-	on_replace1_activate;
-	on_replace_spaces_activate;
-	on_replace_tabs_activate;
-	on_reset_indentation1_activate;
-	on_save1_activate;
-	on_save_all1_activate;
-	on_save_as1_activate;
-	on_search1_activate;
-	on_select_current_lines1_activate;
-	on_select_current_paragraph1_activate;
-	on_send_selection_to_vte1_activate;
-	on_set_file_readonly1_toggled;
-	on_show_color_chooser1_activate;
-	on_show_line_numbers1_toggled;
-	on_show_messages_window1_toggled;
-	on_show_toolbar1_toggled;
-	on_smart_line_indent1_activate;
-	on_spaces1_activate;
-	on_strip_trailing_spaces1_activate;
-	on_tabs1_activate;
-	on_tabs_and_spaces1_activate;
-	on_toggle_case1_activate;
-	on_toolbutton_reload_clicked;
-	on_tv_notebook_switch_page;
-	on_tv_notebook_switch_page_after;
-	on_undo1_activate;
-	on_undo1_activate;
-	on_use_auto_indentation1_toggled;
-	on_website1_activate;
-	on_window_delete_event;
-	on_window_state_event;
-	on_zoom_in1_activate;
-	on_zoom_out1_activate;
-};


Modified: src/signalconn.c.in
32 lines changed, 32 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,32 @@
+
+
+static void builder_connect_func(GtkBuilder *builder, GObject *object,
+	const gchar *signal_name, const gchar *handler_name, GObject *connect_obj,
+	GConnectFlags flags, gpointer user_data)
+{
+	GHashTable *hash = user_data;
+	GCallback callback;
+
+	callback = g_hash_table_lookup(hash, handler_name);
+	g_return_if_fail(callback);
+
+	if (connect_obj == NULL)
+		g_signal_connect_data(object, signal_name, callback, NULL, NULL, flags);
+	else
+		g_signal_connect_object(object, signal_name, callback, connect_obj, flags);
+}
+
+
+void callbacks_connect(GtkBuilder *builder)
+{
+	GHashTable *hash;
+
+	g_return_if_fail(GTK_IS_BUILDER(builder));
+
+	hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+ at callback_map@
+
+	gtk_builder_connect_signals_full(builder, builder_connect_func, hash);
+	g_hash_table_destroy(hash);
+}


Modified: src/ui_utils.c
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -2448,7 +2448,7 @@ void ui_init_builder(void)
 	}
 	g_free(interface_file);
 
-	gtk_builder_connect_signals(builder, NULL);
+	callbacks_connect(builder);
 
 	edit_menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "edit_menu1"));
 	prefs_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "prefs_dialog"));



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list