Hi,
Attached is a patch for g-wrap so that generics with the same name as a
core binding properly extend the core binding. For example, "connect"
can be g_object_connect () in addition to core's "connect", which is the
POSIX C library call.
This patch actually works with guile-gnome's latest code in bzr, and
should work with the 2.7.99 packages as well, although I need to test
that.
You can also get this code via:
$ bzr get http://wingolog.org/bzr/g-wrap/wingo g-wrap
I'm happy now! guile-gnome is out of bitrot, and g-wrap no longer
molests the root module. Now I can actually focus on updating to the
latest gnome library versions, then on apps. I'm not sure what to do
with versions, but I'll make a release soon -- I'm happy enough with the
buildability of the current code.
Cheers,
Andy.
--
http://wingolog.org/
=== modified file 'ChangeLog'
--- ChangeLog 2006-10-26 16:29:08 +0000
+++ ChangeLog 2006-10-26 16:32:15 +0000
@@ -1,3 +1,15 @@
+2006-10-26 Andy Wingo <[EMAIL PROTECTED]>
+
+ * guile/g-wrap/guile-runtime.c (gw_module_binder_proc): Factor
+ functionality out into separate procedures.
+ (make_class_variable): The latent class functionality, unchanged.
+ (allocate_generic_variable, make_generic_variable): The latent
+ generics code, factored out a bit. Brought back in old code to
+ extend existing functions if there is a name conflict. For
+ example, this will allow gtk-list-store-append to be a method on
+ `append', but still fall back on the core binding in the normal
+ cases.
+
2006-10-20 Andy Wingo <[EMAIL PROTECTED]>
* Makefile.am (DIST_SUBDIRS, dist-hook): Trick automake if libffi
=== modified file 'guile/g-wrap/guile-runtime.c'
--- guile/g-wrap/guile-runtime.c 2006-10-26 16:29:08 +0000
+++ guile/g-wrap/guile-runtime.c 2006-10-26 16:33:36 +0000
@@ -323,6 +323,81 @@
*/
static SCM
+make_class_variable (SCM proc, SCM arg)
+{
+ return scm_make_variable (scm_call_1 (proc, arg));
+}
+
+static SCM
+allocate_generic_variable (SCM module, SCM sym)
+{
+ SCM uses, var = SCM_BOOL_F, generic, used = SCM_BOOL_F;
+
+ for (uses=SCM_MODULE_USES(module); !scm_is_null (uses); uses=scm_cdr(uses)) {
+ used = scm_car (uses);
+ var = scm_sym2var (sym, scm_module_lookup_closure (used), SCM_BOOL_F);
+ if (!scm_is_false (var))
+ break;
+ }
+
+ if (scm_is_false (var)) {
+ /* Symbol unbound, make a new generic */
+ generic = scm_apply_0 (scm_sym_make,
+ scm_list_3 (scm_class_generic, k_name, sym));
+ return scm_make_variable (generic);
+ } else if (scm_is_true (scm_call_2 (is_a_p_proc, scm_variable_ref (var),
+ scm_class_generic))) {
+ /* I seem to remember theq is_a_p thing is a hack around GOOPS's deficient
+ macros, but I don't remember. Anyway the existing binding is a generic,
+ let's use it */
+ return var;
+ } else if (scm_is_true (scm_procedure_p (scm_variable_ref (var)))) {
+ /* Make a generic that falls back on the original binding. NB: generics also
+ satisfy procedure?. */
+ generic = scm_apply_0 (scm_sym_make,
+ scm_list_5 (scm_class_generic,
+ k_name, sym,
+ k_default, scm_variable_ref (var)));
+ return scm_make_variable (generic);
+ } else {
+ /* We can't extend the binding, warn and fall through. */
+ scm_display (scm_from_locale_string ("WARNING: generic "),
+ scm_current_error_port ());
+ scm_display (sym, scm_current_error_port ());
+ scm_display (scm_from_locale_string (" incompatibly bound in module "),
+ scm_current_error_port ());
+ scm_display (used, scm_current_error_port ());
+ scm_newline (scm_current_error_port ());
+ return SCM_BOOL_F;
+ }
+}
+
+static SCM
+make_generic_variable (SCM module, SCM sym, SCM procs)
+{
+ SCM var = allocate_generic_variable (module, sym);
+
+ if (!scm_is_false (var)) {
+ SCM generic = scm_variable_ref (var);
+
+ /* hang the methods off the generic */
+ for (; !scm_is_null(procs); procs=SCM_CDR(procs)) {
+ /* entry := #(proc class_name module n_req_args use_optional_args) */
+ SCM entry = SCM_CAR (procs);
+
+ gw_guile_add_subr_method (generic,
+ SCM_SIMPLE_VECTOR_REF (entry, 0),
+ SCM_SIMPLE_VECTOR_REF (entry, 1),
+ SCM_SIMPLE_VECTOR_REF (entry, 2),
+ scm_to_int (SCM_SIMPLE_VECTOR_REF (entry, 3)),
+ scm_is_true (SCM_SIMPLE_VECTOR_REF (entry, 4)));
+ }
+ }
+
+ return var;
+}
+
+static SCM
gw_module_binder_proc (SCM module, SCM sym, SCM definep)
{
SCM latent_variables_hash, pair, var;
@@ -336,33 +411,14 @@
latent_variables_hash = scm_variable_ref (latent_variables_hash);
pair = scm_hashq_ref (latent_variables_hash, sym, SCM_BOOL_F);
- var = scm_make_variable (SCM_BOOL_F);
if (scm_is_false (pair))
return SCM_BOOL_F;
if (scm_is_eq (scm_car (pair), sym_class)) {
- scm_variable_set_x (var, scm_call_1 (scm_cadr (pair), scm_cddr (pair)));
+ var = make_class_variable (scm_cadr (pair), scm_cddr (pair));
} else if (scm_is_eq (scm_car (pair), sym_generic)) {
- SCM generic;
- SCM procs = scm_cdr (pair);
-
- generic = scm_apply_0 (scm_sym_make,
- scm_list_3 (scm_class_generic, k_name, sym));
-
- for (procs=scm_cdr(pair); !scm_is_null(procs); procs=SCM_CDR(procs)) {
- /* entry := #(proc class_name module n_req_args use_optional_args) */
- SCM entry = SCM_CAR (procs);
-
- gw_guile_add_subr_method (generic,
- SCM_SIMPLE_VECTOR_REF (entry, 0),
- SCM_SIMPLE_VECTOR_REF (entry, 1),
- SCM_SIMPLE_VECTOR_REF (entry, 2),
- scm_to_int (SCM_SIMPLE_VECTOR_REF (entry, 3)),
- scm_is_true (SCM_SIMPLE_VECTOR_REF (entry, 4)));
- }
-
- scm_variable_set_x (var, generic);
+ var = make_generic_variable (module, sym, scm_cdr (pair));
} else {
scm_error (scm_from_locale_symbol ("wrong-type"),
"%gw-module-binder",
@@ -372,7 +428,8 @@
return SCM_BOOL_F; /* not reached */
}
- scm_call_3 (module_add_x, module, sym, var);
+ if (!scm_is_false (var))
+ scm_call_3 (module_add_x, module, sym, var);
scm_hashq_remove_x (latent_variables_hash, sym);
return var;
}
_______________________________________________
g-wrap-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/g-wrap-dev