X-Git-Url: http://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/43115cbfefb29535b3e9da83ab247a7f24c6994b..1b42784146ab0d40637c80cf6064bafe679a5a0a:/src/main.c diff --git a/src/main.c b/src/main.c index 6a0c791..c7171c5 100644 --- a/src/main.c +++ b/src/main.c @@ -954,6 +954,59 @@ add_signal_prots(Method *m) out_printf (out, "}\n\n"); } +static char * +interface_type(const char *if_name) +{ + char *rawtype = remove_sep(if_name); + char *end = "", *typename; + + if (!gtk3_ok) { + /* + * EEEK! evil, we should have some sort of option + * to force this for arbitrary interfaces, since + * some are Class and some are Iface. Glib is shite + * in consistency. + */ + + if (strcmp (rawtype, "GtkEditable") == 0 + || strcmp (rawtype, "GTypePlugin") == 0) + { + end = "Class"; + } else { + /* We'll assume Iface is the standard ending */ + end = "Iface"; + } + } else { + /* GTK3 doesn't need Iface end */ + end = "Interface"; + } + + typename = g_strconcat(rawtype, end, (char *)NULL); + g_free(rawtype); + + return typename; +} + +static void +define_parent_interface_refs(Class *c) +{ + GList *li; + + if (!c->interfaces) + return; + + out_printf(out, "\n/* parent class interface implementations */\n"); + for (li = c->interfaces; li != NULL; li = li->next) { + char *name = replace_sep(li->data, '_'); + char *type = interface_type(li->data); + + out_printf (out, "static %s *%s_parent_iface;\n", type, name); + + g_free(name); + g_free(type); + } +} + static void add_enums(Class *c) { @@ -1003,7 +1056,9 @@ add_enums(Class *c) "static guint object_signals[LAST_SIGNAL] = {0};\n\n"); out_printf(out, "/* pointer to the class of our parent */\n"); - out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase); + out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase); + define_parent_interface_refs(c); + out_printf(out, "\n"); } static void @@ -1037,7 +1092,7 @@ add_interface_methods (Class *c, const char *interface) } static void -add_interface_inits (Class *c) +add_interface_inits(Class *c) { GList *li; @@ -1047,39 +1102,19 @@ add_interface_inits (Class *c) out_printf(out, "\n"); for (li = c->interfaces; li != NULL; li = li->next) { - const char *interface = li->data; - const char *end; - char *name = replace_sep (interface, '_'); - char *type = remove_sep (interface); + char *name = replace_sep(li->data, '_'); + char *type = interface_type(li->data); - if(!gtk3_ok) - { - /* EEEK! evil, we should have some sort of option - * to force this for arbitrary interfaces, since - * some are Class and some are Iface. Glib is shite - * in consistency. */ - - if (strcmp (type, "GtkEditable") == 0 || - strcmp (type, "GTypePlugin") == 0) - end = "Class"; - else - // We'll assume Iface is the standard ending - end = "Iface"; - } - else - { - /*GTK3 doesn't need Iface end*/ - end="Interface"; - } - - out_printf (out, "\nstatic void\n" - "___%s_init (%s%s *iface)\n" - "{\n", - name, type, end); + out_printf(out, "static void\n" + "___%s_init (%s *iface)\n" + "{\n", name, type); - add_interface_methods (c, interface); + add_interface_methods(c, li->data); - out_printf (out, "}\n\n"); + out_printf(out, "\t%s_parent_iface\n", name); + out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type); + out_printf(out, "g_type_interface_peek_parent(iface);\n" + "}\n\n"); g_free (name); g_free (type); @@ -3053,6 +3088,35 @@ get_arg_names_for_macro (Method *m) return g_string_free (gs, FALSE); } +static gboolean method_is_void(Method *m) +{ + return !strcmp(m->mtype->name, "void") && !m->mtype->pointer; +} + +static const char *method_err_retval(Method *m) +{ + if (method_is_void(m)) + return "(void)0"; + if (m->onerror) + return m->onerror; + return "0"; +} + +static void +put_interface_parent_handler(Method *m) +{ + const char *errval = method_err_retval(m); + char *name = replace_sep(m->interface, '_'); + char *args = get_arg_names_for_macro(m); + + out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n" + "\t? %s_parent_iface->%s(%s) \\\n" + "\t: %s)\n", args, name, name, m->id, args, errval); + + g_free(name); + g_free(args); +} + static void put_method(Method *m) { @@ -3068,6 +3132,7 @@ put_method(Method *m) g_free(doc); } } + switch(m->method) { case REGULAR_METHOD: if(m->line_no > 0) @@ -3078,7 +3143,18 @@ put_method(Method *m) else /* PUBLIC, PROTECTED */ print_method(out, "", "\n", "", " ", "", "\n", m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE); + + if (m->interface) { + out_addline_outfile(out); + put_interface_parent_handler(m); + } + print_method_body(m, TRUE, TRUE); + + if (m->interface) { + out_printf(out, "#undef PARENT_HANDLER\n"); + } + /* the outfile line was added above */ break; case SIGNAL_FIRST_METHOD: