diff --git a/examples/editor.scm b/examples/editor.scm index f6c19bac..90252523 100644 --- a/examples/editor.scm +++ b/examples/editor.scm @@ -22,8 +22,6 @@ (push-duplicate-handler! 'merge-generics) (use-typelibs - ;; load GObject first to prevent warnings, even if we don't directly need it - (("GObject" "2.0") #:select ()) (("Gio" "2.0") #:renamer (protect* '(application:new receive))) ("Gtk" "3.0") ("Gdk" "3.0")) diff --git a/module/gi/repository.scm b/module/gi/repository.scm index 9508e521..25adca81 100644 --- a/module/gi/repository.scm +++ b/module/gi/repository.scm @@ -34,6 +34,14 @@ (eval-when (expand load eval) (load-extension "libguile-gi" "gig_init_repository")) +(define %gig-duplicate-handlers + (append + (lookup-duplicates-handlers + '(merge-generics replace warn-override-core)) + (list %gig-duplicate-warn) + (lookup-duplicates-handlers + '(last)))) + (define-method (load (info )) (%load-info info LOAD_EVERYTHING)) @@ -45,10 +53,14 @@ (define* (typelib->module module lib #:optional version) (require lib version) - (set! module (cond - ((module? module) module) - ((list? module) (resolve-module module)) - (else (error "not a module: ~A" module)))) + (set! module + (cond + ((module? module) module) + ((list? module) + (let ((m (resolve-module module))) + (set-module-duplicates-handlers! m %gig-duplicate-handlers) + m)) + (else (error "not a module: ~A" module)))) (unless (module-public-interface module) (let ((interface (make-module))) @@ -57,6 +69,17 @@ (set-module-kind! interface 'interface) (set-module-public-interface! module interface))) + (for-each + (lambda (dep) + (module-use! + module + (let ((module (list 'gi (string->symbol dep))) + (lib+version (string-split dep #\-))) + (or (false-if-exception (resolve-interface module)) + (module-public-interface + (apply typelib->module module lib+version)))))) + (immediate-dependencies lib)) + (save-module-excursion (lambda () (set-current-module module) diff --git a/src/gig_repository.c b/src/gig_repository.c index 4aa3f557..9320c045 100644 --- a/src/gig_repository.c +++ b/src/gig_repository.c @@ -23,6 +23,47 @@ #include "gig_flag.h" #include "gig_repository.h" +static SCM module_name_proc = SCM_UNDEFINED; + +static SCM +scm_module_name(SCM module) +{ + if (SCM_UNBNDP(module_name_proc)) + module_name_proc = scm_c_public_ref("guile", "module-name"); + return scm_call_1(module_name_proc, module); +} + +static SCM +gig_duplicate_warn(SCM module, SCM name, SCM int1, SCM val1, SCM int2, SCM val2, SCM var, SCM val) +{ + + SCM _module_s, _name_s, _int1_s, _int2_s, _val1_s, _val2_s; + gchar *module_s, *name_s, *int1_s, *int2_s, *val1_s, *val2_s; + scm_dynwind_begin(0); + + _int1_s = scm_object_to_string(scm_module_name(int1), SCM_UNDEFINED); + _int2_s = scm_object_to_string(scm_module_name(int2), SCM_UNDEFINED); + _val1_s = scm_object_to_string(val1, SCM_UNDEFINED); + _val2_s = scm_object_to_string(val2, SCM_UNDEFINED); + _module_s = scm_object_to_string(scm_module_name(module), SCM_UNDEFINED); + _name_s = scm_object_to_string(name, SCM_UNDEFINED); + + module_s = scm_dynwind_or_bust("%gig-duplicate-warn", scm_to_utf8_string(_module_s)); + name_s = scm_dynwind_or_bust("%gig-duplicate-warn", scm_to_utf8_string(_name_s)); + int1_s = scm_dynwind_or_bust("%gig-duplicate-warn", scm_to_utf8_string(_int1_s)); + int2_s = scm_dynwind_or_bust("%gig-duplicate-warn", scm_to_utf8_string(_int2_s)); + val1_s = scm_dynwind_or_bust("%gig-duplicate-warn", scm_to_utf8_string(_val1_s)); + val2_s = scm_dynwind_or_bust("%gig-duplicate-warn", scm_to_utf8_string(_val2_s)); + + gig_warning_load("%s: `%s' imported from both %s and %s", module_s, name_s, int1_s, int2_s); + gig_debug_load("binding from %s: %s", int1_s, val1_s); + gig_debug_load("binding from %s: %s", int2_s, val2_s); + + scm_dynwind_end(); + + return SCM_BOOL_F; +} + static SCM require(SCM lib, SCM version) { @@ -48,6 +89,31 @@ require(SCM lib, SCM version) return SCM_UNSPECIFIED; } +static SCM +immediate_dependencies(SCM lib) +{ + gchar *_lib, **deps; + guint n_deps; + SCM ret, iter; + + scm_dynwind_begin(0); + _lib = scm_dynwind_or_bust("immediate-dependencies", scm_to_utf8_string(lib)); + deps = g_irepository_get_immediate_dependencies(NULL, _lib); + scm_dynwind_end(); + + if (deps == NULL) + scm_misc_error("immediate-dependencies", "could not find dependencies for ~A", scm_list_1(lib)); + n_deps = g_strv_length(deps); + + ret = scm_make_list(scm_from_uint(n_deps), SCM_UNDEFINED); + iter = ret; + for (guint i = 0; i < n_deps; i++, iter = scm_cdr(iter)) + scm_set_car_x(iter, scm_from_utf8_string(deps[i])); + g_strfreev(deps); + + return ret; +} + static SCM infos(SCM lib) { @@ -349,7 +415,9 @@ prepend_search_path(SCM s_dir) void gig_init_repository() { + scm_c_define_gsubr("%gig-duplicate-warn", 8, 0, 0, gig_duplicate_warn); scm_c_define_gsubr("require", 1, 1, 0, require); + scm_c_define_gsubr("immediate-dependencies", 1, 0, 0, immediate_dependencies); scm_c_define_gsubr("infos", 1, 0, 0, infos); scm_c_define_gsubr("info", 2, 0, 0, info); scm_c_define_gsubr("%load-info", 1, 1, 0, load);