From 9b591a326d98245379213aecaf39d1f44f4ff5a7 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sat, 8 Feb 2020 12:06:09 -0500 Subject: [PATCH] Clean up get_type implementations a bit. To simplify future code using the G_DEFINE_TYPE_xxx macros, move all the interface registration out of the get_type/register_type functions and into a separate function. And while we are doing this, factor out some common code between the different add_xxx_get_type functions. Should be no functional change. --- src/main.c | 386 +++++++++++++++++++++++++---------------------------- 1 file changed, 181 insertions(+), 205 deletions(-) diff --git a/src/main.c b/src/main.c index 5767215..61125d8 100644 --- a/src/main.c +++ b/src/main.c @@ -1122,254 +1122,230 @@ add_interface_inits(Class *c) } static void -add_interface_infos (void) +add_interface_infos(Class *c, gboolean static_storage) { GList *li; - for (li = ((Class *)class)->interfaces; - li != NULL; - li = li->next) { - char *name = replace_sep (li->data, '_'); - out_printf (out, - "\t\tstatic const GInterfaceInfo %s_info = {\n" - "\t\t\t(GInterfaceInitFunc) ___%s_init,\n" - "\t\t\tNULL,\n" - "\t\t\tNULL\n" - "\t\t};\n\n", - name, name); - g_free (name); + + for (li = c->interfaces; li; li = li->next) { + char *name = replace_sep(li->data, '_'); + out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n" + "\t\t(GInterfaceInitFunc) ___%s_init,\n" + "\t\tNULL,\n" + "\t\tNULL\n" + "\t};\n", + static_storage ? "static " : "", + name, name); + g_free(name); } + + out_printf(out, "\n"); } static void -add_interfaces (void) +define_add_interfaces(Class *c) { GList *li; - for (li = ((Class *)class)->interfaces; - li != NULL; - li = li->next) { - char *name = replace_sep (li->data, '_'); - char *type = make_pre_macro (li->data, "TYPE"); - out_printf (out, - "\t\tg_type_add_interface_static (type,\n" - "\t\t\t%s,\n" - "\t\t\t&%s_info);\n", - type, - name); + if (!c->interfaces) + return; - g_free (type); - g_free (name); + out_printf(out, "static void ___add_interfaces(GType type)\n{\n"); + add_interface_infos(c, TRUE); + + for (li = c->interfaces; li; li = li->next) { + char *type = make_pre_macro(li->data, "TYPE"); + char *name = replace_sep(li->data, '_'); + + out_printf(out, "\tg_type_add_interface_static\n" + "\t\t( type\n" + "\t\t, %s\n" + "\t\t, &%s_info\n" + "\t\t);\n", + type, name); + + g_free(name); + g_free(type); } + + out_printf(out, "}\n\n"); } static void -add_dynamic_interfaces(void) +define_dynamic_add_interfaces(Class *c) { - GList *li = ((Class *)class)->interfaces; + GList *li; - if (li) { - /* - * Hack to work around bug in g_type_module_add_interface, - * which will fail to add an interface to types that derive - * from something that also implements the same interface. - * - * The actual GType system does not have any such problem, - * and the GTypeModule implementation details relied upon - * here have not changed once since the feature was first - * implemented almost 20 years ago. - */ - out_printf(out, "\t\tstruct _ModuleInterfaceInfo {\n" - "\t\t\tgboolean loaded;\n" - "\t\t\tGType instance_type;\n" - "\t\t\tGType interface_type;\n" - "\t\t\tGInterfaceInfo info;\n" - "\t\t} *modinfo;\n"); - } + if (!c->interfaces) + return; - for (; li; li = li->next) { - char *name = replace_sep(li->data, '_'); + out_printf(out, "static void ___add_interfaces" + "(GTypeModule *type_module, GType type)\n" + "{\n"); + add_interface_infos(c, FALSE); + + /* + * Hack to work around bug in g_type_module_add_interface, + * which will fail to add an interface to types that derive + * from something that also implements the same interface. + * + * The actual GType system does not have any such problem, + * and the GTypeModule implementation details relied upon + * here have not changed once since the feature was first + * implemented almost 20 years ago. + */ + out_printf(out, "\tstruct _ModuleInterfaceInfo {\n" + "\t\tgboolean loaded;\n" + "\t\tGType instance_type;\n" + "\t\tGType interface_type;\n" + "\t\tGInterfaceInfo info;\n" + "\t} *modinfo;\n"); + + for (li = c->interfaces; li; li = li->next) { char *type = make_pre_macro(li->data, "TYPE"); + char *name = replace_sep(li->data, '_'); out_printf(out, "\n" - "\t\tmodinfo = g_malloc(sizeof *modinfo);\n" - "\t\tmodinfo->loaded = TRUE;\n" - "\t\tmodinfo->instance_type = %s_type_id;\n" - "\t\tmodinfo->interface_type = %s;\n" - "\t\tmodinfo->info = %s_info;\n" - "\t\tg_type_add_interface_dynamic\n" - "\t\t\t( modinfo->instance_type\n" - "\t\t\t, modinfo->interface_type\n" - "\t\t\t, G_TYPE_PLUGIN(type_module)\n" - "\t\t\t);\n" - "\t\ttype_module->interface_infos = g_slist_prepend\n" - "\t\t\t( type_module->interface_infos\n" - "\t\t\t, modinfo\n" - "\t\t\t);\n", funcbase, type, name); + "\tmodinfo = g_malloc(sizeof *modinfo);\n" + "\tmodinfo->loaded = TRUE;\n" + "\tmodinfo->instance_type = type;\n" + "\tmodinfo->interface_type = %s;\n" + "\tmodinfo->info = %s_info;\n" + "\tg_type_add_interface_dynamic\n" + "\t\t( modinfo->instance_type\n" + "\t\t, modinfo->interface_type\n" + "\t\t, G_TYPE_PLUGIN(type_module)\n" + "\t\t);\n" + "\ttype_module->interface_infos = g_slist_prepend\n" + "\t\t( type_module->interface_infos\n" + "\t\t, modinfo\n" + "\t\t);\n", + type, name); - g_free(type); g_free(name); + g_free(type); } + + out_printf(out, "}\n\n"); +} + +static void add_type_info(void) +{ + out_printf(out, "\tstatic const GTypeInfo info = {\n" + "\t\tsizeof (%sClass),\n" + "\t\t(GBaseInitFunc) NULL,\n" + "\t\t(GBaseFinalizeFunc) NULL,\n" + "\t\t(GClassInitFunc) %s_class_init,\n" + "\t\t(GClassFinalizeFunc) NULL,\n" + "\t\tNULL /* class_data */,\n" + "\t\tsizeof (%s),\n" + "\t\t%d /* n_preallocs */,\n" + "\t\t(GInstanceInitFunc) %s_init,\n" + "\t\tNULL\n" + "\t};\n\n", + typebase, funcbase, typebase, prealloc, funcbase); } static void add_get_type(void) { - /*char *chunk_size = ((Class*)class)->chunk_size;*/ + Class *c = (Class *)class; - out_printf(out, - "GType\n" - "%s_get_type (void)\n" - "{\n" - "\tstatic GType type = 0;\n\n" - "\tif ___GOB_UNLIKELY(type == 0) {\n" - "\t\tstatic const GTypeInfo info = {\n" - "\t\t\tsizeof (%sClass),\n" - "\t\t\t(GBaseInitFunc) NULL,\n" - "\t\t\t(GBaseFinalizeFunc) NULL,\n" - "\t\t\t(GClassInitFunc) %s_class_init,\n" - "\t\t\t(GClassFinalizeFunc) NULL,\n" - "\t\t\tNULL /* class_data */,\n" - "\t\t\tsizeof (%s),\n" - "\t\t\t%d /* n_preallocs */,\n" - "\t\t\t(GInstanceInitFunc) %s_init,\n" - "\t\t\tNULL\n" - "\t\t};\n\n", - funcbase, typebase, funcbase, typebase, prealloc, funcbase); - - add_interface_infos (); + define_add_interfaces(c); - out_printf (out, - "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n", - pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0"); + out_printf(out, "GType %s_get_type(void)\n" + "{\n" + "\tstatic GType type = 0;\n", + funcbase); - add_interfaces (); + add_type_info(); - /* - if(chunk_size) { - out_printf(out, - "#if %s > 0\n" - "\t\tgtk_type_set_chunk_alloc(type, %s);\n" - "#endif\n", - chunk_size, chunk_size); - } - */ - out_printf(out, - "\t}\n\n" - "\treturn type;\n" - "}\n\n"); + out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n" + "\t\ttype = g_type_register_static\n" + "\t\t\t( %s\n" + "\t\t\t, \"%s\"\n" + "\t\t\t, &info\n" + "\t\t\t, (GTypeFlags)%s\n" + "\t\t\t);\n", + pmacrotype, typebase, + c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0"); + + if (c->interfaces) + out_printf(out, "\t\t___add_interfaces(type);\n"); + + out_printf(out, "\t}\n\n" + "\treturn type;\n" + "}\n\n"); } static void -add_dynamic_get_type (void) +add_dynamic_get_type(void) { - out_printf(out, - "static GType %s_type_id;\n\n" - "GType\n" - "%s_get_type (void)\n" - "{\n" - "\treturn %s_type_id;\n" - "}\n\n", - funcbase, funcbase, funcbase); - - out_printf(out, - "void\n" - "%s_register_type (GTypeModule *type_module)\n" - "{\n" - "\tstatic const GTypeInfo info = {\n" - "\t\tsizeof (%sClass),\n" - "\t\t(GBaseInitFunc) NULL,\n" - "\t\t(GBaseFinalizeFunc) NULL,\n" - "\t\t(GClassInitFunc) %s_class_init,\n" - "\t\t(GClassFinalizeFunc) NULL,\n" - "\t\tNULL /* class_data */,\n" - "\t\tsizeof (%s),\n" - "\t\t%d /* n_preallocs */,\n" - "\t\t(GInstanceInitFunc) %s_init,\n" - "\t\tNULL\n" - "\t};\n\n", - funcbase, typebase, funcbase, typebase, prealloc, funcbase); - - add_interface_infos(); - - out_printf(out, - "\t%s_type_id = g_type_module_register_type(\n" - "\t\ttype_module,\n" - "\t\t%s,\n" - "\t\t\"%s\",\n" - "\t\t&info,\n" - "\t\t(GTypeFlags)%s\n" - "\t);\n\n" - "\t{\n", - funcbase, pmacrotype, typebase, - ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0"); - - add_dynamic_interfaces(); + Class *c = (Class *)class; + + define_dynamic_add_interfaces(c); + + out_printf(out, "static GType %s_type_id;\n\n" + "GType %s_get_type(void)\n" + "{\n" + "\treturn %s_type_id;\n" + "}\n\n", + funcbase, funcbase, funcbase); + + out_printf(out, "void %s_register_type(GTypeModule *type_module)\n" + "{\n", + funcbase); + + add_type_info(); + + out_printf(out, "\t%s_type_id = g_type_module_register_type\n" + "\t\t( type_module\n" + "\t\t, %s\n" + "\t\t, \"%s\"\n" + "\t\t, &info\n" + "\t\t, (GTypeFlags)%s\n" + "\t\t);\n", + funcbase, pmacrotype, typebase, + c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0"); + + if (c->interfaces) { + out_printf(out, "\t___add_interfaces" + "(type_module, %s_type_id);\n", + funcbase); + } - out_printf(out, - "\t}\n" - "}\n\n"); + out_printf(out, "}\n\n"); } static void -add_bonobo_object_get_type (void) +add_bonobo_object_get_type(void) { - /* char *chunk_size = ((Class*)class)->chunk_size; */ - /* _vicious_ spanks seth with a rusty nail - out_printf(out, - "\n#warning \"Bonobo isn't fully ported to glib 2.0 and " - "gob2 doesn't officially support it yet. It'd be safer " - "and a lot more fun to blow goats.\"\n"); - */ + Class *c = (Class *)class; - out_printf (out, - "GType\n" - "%s_get_type (void)\n" /* 1 */ - "{\n" - "\tstatic GType type = 0;\n\n" - "\tif ___GOB_UNLIKELY(type == 0) {\n" - "\t\tstatic const GTypeInfo info = {\n" - "\t\t\tsizeof (%sClass),\n" /* 2 */ - "\t\t\t(GBaseInitFunc) NULL,\n" - "\t\t\t(GBaseFinalizeFunc) NULL,\n" - "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */ - "\t\t\tNULL, /* class_finalize */\n" - "\t\t\tNULL, /* class_data */\n" - "\t\t\tsizeof (%s),\n" /* 4 */ - "\t\t\t0, /* n_preallocs */\n" - "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */ - "\t\t\tNULL\n" - "\t\t};\n\n", - funcbase /* 1 */, - typebase /* 2 */, - funcbase /* 3 */, - typebase /* 4 */, - funcbase /* 5 */); - - add_interface_infos (); + define_add_interfaces(c); - out_printf (out, - "\t\ttype = bonobo_type_unique (\n" - "\t\t\tBONOBO_OBJECT_TYPE,\n" - "\t\t\tPOA_%s__init, NULL,\n" /* 1 */ - "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */ - "\t\t\t&info, \"%s\");\n", /* 3 */ - ((Class*)class)->bonobo_object_class /* 1 */, - typebase /* 2 */, - typebase /* 3 */); - - add_interfaces (); - - /*if(chunk_size) { - out_printf(out, - "#if %s > 0\n" - "\t\tgtk_type_set_chunk_alloc(type, %s);\n" - "#endif\n", - chunk_size, chunk_size); - }*/ - out_printf(out, - "\t}\n\n" - "\treturn type;\n" - "}\n\n"); + out_printf (out, "GType %s_get_type(void)\n" + "{\n" + "\tstatic GType type = 0;\n", + funcbase); + + add_type_info(); + + out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n" + "\t\ttype = bonobo_type_unique\n" + "\t\t\t( BONOBO_OBJECT_TYPE\n" + "\t\t\t, POA_%s__init, NULL\n" + "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n" + "\t\t\t, &info\n" + "\t\t\t, \"%s\"\n" + "\t\t\t);\n", + c->bonobo_object_class, typebase, typebase); + + if (((Class *)class)->interfaces) + out_printf(out, "\t\t___add_interfaces(type);\n"); + + out_printf(out, "\t}\n\n" + "\treturn type;\n" + "}\n\n"); } static void -- 2.43.0