+
+ if (!c->interfaces)
+ return;
+
+ 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"
+ "\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(name);
+ g_free(type);
+ }
+
+ out_printf(out, "}\n\n");
+}
+
+static void define_add_privates(Class *c)
+{
+ const char *addprivate = c->dynamic
+ ? "G_ADD_PRIVATE_DYNAMIC"
+ : "G_ADD_PRIVATE";
+
+ if (!privates)
+ return;
+
+ out_printf(out, "#ifdef %s\n"
+ "#define ___add_privates() %s(%s)\n"
+ "#else\n"
+ "#define ___add_privates()\n"
+ "#endif\n\n",
+ addprivate, addprivate, typebase);
+}
+
+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)
+{
+ Class *c = (Class *)class;
+
+ define_add_interfaces(c);
+ define_add_privates(c);
+
+ out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
+ "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
+ "\t(GTypeFlags)%s,\n",
+ typebase, funcbase, pmacrotype,
+ c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
+
+ if (privates)
+ out_printf(out, "\t___add_privates();\n");
+
+ if (c->interfaces)
+ out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
+
+ /* Fallback for GLib < 2.4 */
+ out_printf(out, ");\n\n"
+ "#else\n\n"
+ "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 = 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"
+ "#endif\n\n");
+}
+
+static void
+add_dynamic_get_type(void)
+{
+ Class *c = (Class *)class;
+
+ define_dynamic_add_interfaces(c);
+ define_add_privates(c);
+
+ /*
+ * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
+ * some reason it defines an xxx_register_type function with internal
+ * linkage. This is kind of weird so we have to work around that.
+ */
+ out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
+ "static void %s_class_finalize(%sClass *c) { }\n\n"
+ "#define %s_register_type ___register_type\n",
+ funcbase, typebase, funcbase);
+
+ out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
+ "\t(GTypeFlags)%s,\n",
+ typebase, funcbase, pmacrotype,
+ c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
+
+ if (privates)
+ out_printf(out, "\t___add_privates();\n");
+
+ if (c->interfaces) {
+ out_printf(out, "\t___add_interfaces"
+ "(type_module, %s_type_id);\n", funcbase);
+ }
+
+ out_printf(out, ");\n"
+ "#undef %s_register_type\n\n"
+ "void %s_register_type(GTypeModule *type_module)\n"
+ "{\n"
+ "\t___register_type(type_module);\n"
+ "}\n\n",
+ funcbase, funcbase);
+
+ /* Fallback for GLib < 2.14 */
+ out_printf(out, "#else\n\n"
+ "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, "}\n\n"
+ "#endif\n\n");
+}
+
+static void
+add_bonobo_object_get_type(void)
+{
+ Class *c = (Class *)class;
+
+ define_add_interfaces(c);
+
+ 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
+add_overrides(Class *c, const char *oname,
+ gboolean did_base_obj)
+{
+ GList *li;
+ GHashTable *done;
+ char *s;
+
+ done = g_hash_table_new (g_str_hash, g_str_equal);
+ if (did_base_obj) {
+ s = g_strdup ("GObject");
+ g_hash_table_insert (done, s, s);
+ }
+ for (li = c->nodes; li != NULL; li = li->next) {
+ Node *n = li->data;
+ char *f;
+ Method *m = (Method *)n;
+ if(n->type != METHOD_NODE ||
+ m->method != OVERRIDE_METHOD)
+ continue;
+
+ s = remove_sep(m->otype);
+
+ if(g_hash_table_lookup(done, s)) {
+ g_free(s);
+ continue;
+ }
+ g_hash_table_insert(done, s, s);
+
+ f = replace_sep(m->otype, '_');
+ gob_strdown(f);
+
+ out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
+ s, f, s, oname);
+
+ g_free(f);
+ }
+ g_hash_table_foreach (done, (GHFunc)g_free, NULL);
+ g_hash_table_destroy (done);
+}
+
+static char *
+make_run_signal_flags(Method *m, gboolean last)
+{
+ GList *li;
+ GString *gs;
+ char *flags[] = {
+ "RUN_FIRST",
+ "RUN_LAST",
+ "RUN_CLEANUP",
+ "NO_RECURSE",
+ "DETAILED",
+ "ACTION",
+ "NO_HOOKS",
+ NULL
+ };
+
+ gs = g_string_new(NULL);
+
+ if(last)
+ g_string_assign(gs, "G_SIGNAL_RUN_LAST");
+ else
+ g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
+
+ if(m->scope == PUBLIC_SCOPE)
+ g_string_append(gs, " | G_SIGNAL_ACTION");
+
+ for(li = m->flags; li; li = li->next) {
+ char *flag = li->data;
+ int i;
+ for(i=0;flags[i];i++) {
+ if(strcmp(flags[i], flag)==0)
+ break;
+ }
+ /* if we haven't found it in our list */
+ if( ! flags[i]) {
+ error_printf(GOB_WARN, m->line_no,
+ "Unknown flag '%s' used, "
+ "perhaps it was misspelled",
+ flag);
+ }
+ g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
+ }
+
+ {
+ char *ret = gs->str;
+ g_string_free(gs, FALSE);
+ return ret;
+ }
+}
+
+
+static void
+add_signals(Class *c)
+{
+ GList *li;
+
+ out_printf(out, "\n");
+ for(li=c->nodes;li;li=g_list_next(li)) {
+ Node *n = li->data;
+ char *mar, *sig, *flags;
+ gboolean is_none, last = FALSE;
+ Method *m = (Method *)n;
+
+ if(n->type != METHOD_NODE ||
+ (m->method != SIGNAL_FIRST_METHOD &&
+ m->method != SIGNAL_LAST_METHOD))
+ continue;
+
+ if(m->method == SIGNAL_FIRST_METHOD)
+ last = FALSE;
+ else
+ last = TRUE;
+
+ if(g_hash_table_lookup(marsh, m))
+ mar = g_strconcat("___marshal_",
+ (char *)g_hash_table_lookup(marsh, m),
+ NULL);
+ else
+ mar = g_strdup("g_cclosure_marshal_VOID__VOID");
+
+ is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
+
+ sig = g_strdup (m->id);
+ gob_strup (sig);
+ flags = make_run_signal_flags (m, last);
+ out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
+ "\t\tg_signal_new (%s,\n"
+ "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
+ "\t\t\t(GSignalFlags)(%s),\n"
+ "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
+ "\t\t\tNULL, NULL,\n"
+ "\t\t\t%s,\n"
+ "\t\t\tG_TYPE_%s, %d",
+ sig, m->signal_name /*m->id* if not given signal_name*/,
+ flags,
+ typebase, m->id, mar,
+ (char *)m->gtktypes->data,
+ is_none ? 0 : g_list_length(m->gtktypes->next));
+ g_free(mar);
+ g_free(sig);
+ g_free(flags);
+
+ if( ! is_none) {
+ GList *l;
+ char *t;
+ for(l = m->gtktypes->next; l != NULL; l = l->next) {
+ char *str = l->data;
+ if (strncmp (str, "BOXED_", 6) == 0)
+ t = g_strdup (&(str[6]));
+ else
+ t = g_strconcat ("G_TYPE_", str, NULL);
+ out_printf (out, ",\n\t\t\t%s", t);
+ g_free (t);
+ }
+ }
+
+ out_printf(out, ");\n");
+
+ if(strcmp(m->gtktypes->data, "NONE") != 0 ||
+ ! is_none) {
+ GList *gl, *al;
+ out_printf(out, "\tif ___GOB_UNLIKELY(");
+ if(strcmp(m->gtktypes->data, "NONE") != 0) {
+ out_printf(out, "sizeof(");
+ print_type(out, m->mtype, FALSE);
+ out_printf(out, "%s",
+ m->mtype->postfix ?
+ m->mtype->postfix : "");
+ out_printf(out, ") != sizeof(%s) || ",
+ get_cast(m->gtktypes->data, FALSE));
+ }
+
+ for(al = m->args->next, gl = m->gtktypes->next;
+ al != NULL && gl != NULL;
+ al = al->next, gl = gl->next) {
+ FuncArg *arg = al->data;
+ char *gtkarg = gl->data;
+
+ out_printf(out, "sizeof(");
+ print_type(out, arg->atype, FALSE);
+ out_printf(out, "%s",
+ arg->atype->postfix ?
+ arg->atype->postfix : "");
+ out_printf(out, ") != sizeof(%s) || ",
+ get_cast(gtkarg, FALSE));
+ }
+
+ out_printf (out,
+ "parent_class == NULL /* avoid warning */");
+
+ out_printf(out, ") {\n"
+ "\t\tg_error(\"%s line %d: Type mismatch "
+ "of \\\"%s\\\" signal signature\");\n"
+ "\t}\n",
+ filename, m->line_no, m->id);
+
+ }
+ }
+}
+
+static void
+set_def_handlers(Class *c, const char *oname)
+{
+ GList *li;
+ gboolean set_line = FALSE;
+
+ out_printf(out, "\n");
+ for(li = c->nodes; li; li = g_list_next(li)) {
+ Node *n = li->data;
+ Method *m = (Method *)n;
+
+ if(n->type != METHOD_NODE ||
+ (m->method != SIGNAL_FIRST_METHOD &&
+ m->method != SIGNAL_LAST_METHOD &&
+ m->method != VIRTUAL_METHOD &&
+ m->method != OVERRIDE_METHOD))
+ continue;
+
+ if(m->line_no > 0 && m->cbuf) {
+ out_addline_infile(out, m->line_no);
+ set_line = TRUE;
+ } else if(set_line) {
+ out_addline_outfile(out);
+ set_line = FALSE;
+ }
+
+
+ if (m->method == OVERRIDE_METHOD) {
+ char *s;
+ s = replace_sep (m->otype, '_');
+ gob_strdown (s);
+
+ if (need_dispose &&
+ dispose_handler != NULL &&
+ strcmp (m->id, "dispose") == 0)
+ out_printf (out, "\tg_object_class->dispose "
+ "= ___dispose;\n");
+ else if (need_finalize &&
+ finalize_handler &&
+ strcmp(m->id, "finalize") == 0)
+ out_printf(out,
+ "\tg_object_class->finalize = ___finalize;\n");
+ else if (m->cbuf != NULL)
+ out_printf(out,
+ "\t%s_class->%s = ___%x_%s_%s;\n",
+ s, m->id, (guint)m->unique_id,
+ funcbase, m->id);
+ else
+ out_printf(out, "\t%s_class->%s = NULL;\n",
+ s, m->id);
+ } else {
+ if(m->cbuf)
+ out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
+ oname, m->id,
+ funcbase, m->id);
+ else
+ out_printf(out, "\t%s->%s = NULL;\n",
+ oname, m->id);
+ }
+ }
+ if(set_line)
+ out_addline_outfile(out);
+}
+
+static void
+make_argument (Argument *a)
+{
+ GString *flags;
+ GList *l;
+ char *s;
+ char *argflags[] = {
+ "CONSTRUCT",
+ "CONSTRUCT_ONLY",
+ "LAX_VALIDATION",
+ "PRIVATE",
+ NULL
+ };
+
+ flags = g_string_new ("(GParamFlags)(");
+
+ if(a->get && a->set)
+ g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
+ else if(a->get)
+ g_string_append (flags, "G_PARAM_READABLE");
+ else
+ g_string_append (flags, "G_PARAM_WRITABLE");
+
+ g_assert(a->get || a->set);
+
+ for (l = a->flags; l != NULL; l = l->next) {
+ char *flag = l->data;
+ int i;
+ if(strcmp (flag, "READABLE") == 0 ||
+ strcmp (flag, "WRITABLE") == 0) {
+ error_print(GOB_WARN, a->line_no,
+ "READABLE and "
+ "WRITABLE argument flags are "
+ "set automatically");
+ continue;
+ }
+ for(i = 0; argflags[i]; i++) {
+ if(strcmp(argflags[i], flag)==0)
+ break;
+ }
+ g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
+ }
+
+ g_string_append (flags, ")");
+
+ s = g_strdup(a->name);
+ gob_strup (s);
+ if (!strcmp (a->gtktype, "ENUM"))
+ out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
+ "\t\tG_TYPE_ENUM, 0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ if (!strcmp (a->gtktype, "FLAGS"))
+ out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
+ "\t\tG_TYPE_FLAGS, 0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "OBJECT"))
+ out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
+ "\t\tG_TYPE_OBJECT,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "STRING"))
+ out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
+ "\t\tNULL,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "INT"))
+ out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
+ "\t\tG_MININT, G_MAXINT,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "UINT"))
+ out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
+ "\t\t0, G_MAXUINT,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "INT"))
+ out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
+ "\t\tG_MININT, G_MAXINT,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "CHAR"))
+ out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
+ "\t\t-128, 127,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "UCHAR"))
+ out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
+ "\t\t0, 0xFF,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "BOOL") ||
+ !strcmp (a->gtktype, "BOOLEAN"))
+ out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
+ "\t\tFALSE,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "LONG"))
+ out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
+ "\t\tG_MINLONG, G_MAXLONG,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "ULONG"))
+ out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
+ "\t\t0, G_MAXULONG,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "INT64"))
+ out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
+ "\t\tG_MININT64, G_MAXINT64,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "UINT64"))
+ out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
+ "\t\t0, G_MAXUINT64,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "FLOAT"))
+ out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
+ "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "DOUBLE"))
+ out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
+ "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
+ "\t\t0,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else if (!strcmp (a->gtktype, "POINTER"))
+ out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
+ "\t\t%s);\n",
+ a->name, flags->str);
+ else
+ error_printf (GOB_ERROR, a->line_no,
+ "%s type is not supported for arguments, try using properties",
+ a->gtktype);
+
+ out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
+ "\t\tPROP_%s, param_spec);\n", s);
+
+
+ g_free(s);
+ g_string_free(flags, TRUE);
+}
+
+#define value_for_print(str, alt) (str != NULL ? str : alt)
+
+static void
+make_property (Property *p)
+{
+ char *s;
+
+ if (p->get == NULL && p->set == NULL) {
+ error_print (GOB_ERROR, p->line_no,
+ "Property has no getter nor setter");
+ }
+
+ if (p->override) {
+ if (p->flags != NULL)
+ error_print (GOB_WARN, p->line_no,
+ "Overridden property, flags ignored");
+ if (p->nick != NULL)
+ error_print (GOB_WARN, p->line_no,
+ "Overridden property, nick ignored");
+ if (p->blurb != NULL)
+ error_print (GOB_WARN, p->line_no,
+ "Overridden property, blurb ignored");
+ if (p->minimum != NULL)
+ error_print (GOB_WARN, p->line_no,
+ "Overridden property, minimum ignored");
+ if (p->maximum != NULL)
+ error_print (GOB_WARN, p->line_no,
+ "Overridden property, maximum ignored");
+ if (p->default_value != NULL)
+ error_print (GOB_WARN, p->line_no,
+ "Overridden property, default_value ignored");
+
+ s = g_strdup (p->name);
+ gob_strup (s);
+ out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
+ "\t\tPROP_%s,\n"
+ "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
+ g_free (s);
+ } else {
+ GString *flags;
+ GList *l;
+ char *argflags[] = {
+ "CONSTRUCT",
+ "CONSTRUCT_ONLY",
+ "LAX_VALIDATION",
+ "PRIVATE",
+ NULL
+ };
+
+ flags = g_string_new ("(GParamFlags)(");
+
+ if (p->get != NULL && p->set != NULL)
+ g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
+ else if (p->get != NULL)
+ g_string_append (flags, "G_PARAM_READABLE");
+ else
+ g_string_append (flags, "G_PARAM_WRITABLE");
+
+
+ for (l = p->flags; l != NULL; l = l->next) {
+ char *flag = l->data;
+ int i;
+ if(strcmp (flag, "READABLE") == 0 ||
+ strcmp (flag, "WRITABLE") == 0) {
+ error_print(GOB_WARN, p->line_no,
+ "READABLE and "
+ "WRITABLE argument flags are "
+ "set automatically");
+ continue;
+ }
+ for(i = 0; argflags[i]; i++) {
+ if(strcmp(argflags[i], flag)==0)
+ break;
+ }
+ g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
+ }
+
+ g_string_append (flags, ")");
+
+ if (strcmp (p->gtktype, "CHAR") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_char\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "-128"),
+ value_for_print (p->maximum, "127"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "UCHAR") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "0"),
+ value_for_print (p->maximum, "0xFF"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->default_value, "FALSE"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "INT") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_int\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "G_MININT"),
+ value_for_print (p->maximum, "G_MAXINT"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "UINT") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_uint\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "0"),
+ value_for_print (p->maximum, "G_MAXUINT"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "LONG") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_long\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "G_MINLONG"),
+ value_for_print (p->maximum, "G_MAXLONG"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "ULONG") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "0"),
+ value_for_print (p->maximum, "G_MAXULONG"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "INT64") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_int64\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "G_MININT64"),
+ value_for_print (p->maximum, "G_MAXINT64"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "UINT64") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "0"),
+ value_for_print (p->maximum, "G_MAXUINT64"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "ENUM") == 0) {
+ char *type = make_me_type (p->extra_gtktype,
+ "G_TYPE_ENUM");
+ out_printf (out, "\tparam_spec = g_param_spec_enum\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* enum_type */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ type,
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ g_free (type);
+ } else if (strcmp (p->gtktype, "FLAGS") == 0) {
+ char *type = make_me_type (p->extra_gtktype,
+ "G_TYPE_FLAGS");
+ out_printf (out, "\tparam_spec = g_param_spec_flags\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* flags_type */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ type,
+ value_for_print (p->default_value, "0"),
+ flags->str);
+ g_free (type);
+ } else if (strcmp (p->gtktype, "FLOAT") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_float\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "-G_MAXFLOAT"),
+ value_for_print (p->maximum, "G_MAXFLOAT"),
+ value_for_print (p->default_value, "0.0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_double\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* minimum */,\n"
+ "\t\t %s /* maximum */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->minimum, "-G_MAXDOUBLE"),
+ value_for_print (p->maximum, "G_MAXDOUBLE"),
+ value_for_print (p->default_value, "0.0"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "STRING") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_string\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* default_value */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ value_for_print (p->default_value, "NULL"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "PARAM") == 0) {
+ char *type = make_me_type (p->extra_gtktype,
+ "G_TYPE_PARAM");
+ out_printf (out, "\tparam_spec = g_param_spec_param\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* param_type */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ type,
+ flags->str);
+ g_free (type);
+ } else if (strcmp (p->gtktype, "BOXED") == 0) {
+ char *type = make_me_type (p->extra_gtktype,
+ "G_TYPE_BOXED");
+ out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* boxed_type */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ type,
+ flags->str);
+ g_free (type);
+ } else if (strcmp (p->gtktype, "POINTER") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ flags->str);
+ /* FIXME: VALUE_ARRAY */
+ } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
+ out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ flags->str);
+ } else if (strcmp (p->gtktype, "OBJECT") == 0) {
+ char *type = make_me_type (p->extra_gtktype,
+ "G_TYPE_BOXED");
+ out_printf (out, "\tparam_spec = g_param_spec_object\n"
+ "\t\t(\"%s\" /* name */,\n"
+ "\t\t %s /* nick */,\n"
+ "\t\t %s /* blurb */,\n"
+ "\t\t %s /* object_type */,\n"
+ "\t\t %s);\n",
+ value_for_print (p->canonical_name, p->name),
+ value_for_print (p->nick, "NULL"),
+ value_for_print (p->blurb, "NULL"),
+ type,
+ flags->str);
+ g_free (type);
+ } else {
+ error_printf (GOB_ERROR, p->line_no,
+ "%s type is not supported by properties",
+ p->gtktype);
+ }
+
+ s = g_strdup (p->name);
+ gob_strup (s);
+ out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
+ "\t\tPROP_%s,\n"
+ "\t\tparam_spec);\n", s);
+ g_free (s);
+
+ g_string_free (flags, TRUE);
+ }
+}
+
+static void
+make_arguments(Class *c)
+{
+ GList *li;
+ if (get_properties > 0)
+ out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
+ if (set_properties > 0)
+ out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
+ out_printf (out, " {\n");
+ for (li = c->nodes; li != NULL; li = li->next) {
+ Node *n = li->data;
+ if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
+ || n->type == ARGUMENT_NODE) {
+ out_printf(out, "\tGParamSpec *param_spec;\n\n");
+ break;
+ }
+ }
+
+ for (li = c->nodes; li != NULL; li = li->next) {
+ Node *n = li->data;
+ if (n->type == PROPERTY_NODE)
+ make_property ((Property *)n);
+ else if (n->type == ARGUMENT_NODE)
+ make_argument ((Argument *)n);
+ }
+ out_printf(out, " }\n");
+}
+
+static void
+print_initializer(Method *m, Variable *v)
+{
+ char *root;
+
+ if(v->glade_widget)
+ return;
+
+ if(v->initializer == NULL)
+ return;
+
+ if(v->scope == PRIVATE_SCOPE)
+ root = g_strconcat(((FuncArg *)m->args->data)->name,
+ "->_priv", NULL);
+ else
+ root = g_strdup(((FuncArg *)m->args->data)->name);
+
+ if(v->initializer_line > 0)
+ out_addline_infile(out, v->initializer_line);
+
+ if (v->initializer_simple)
+ out_printf(out, "\t%s->%s = %s;\n",
+ root, v->id, v->initializer);
+ else if (strcmp(v->id, "_glade_xml") == 0)
+ /* This is OK, this v->initializer string is set internally
+ and it will eat exactly one string! */
+ out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
+ else
+ out_printf(out, "%s", v->initializer);
+
+ if(v->initializer_line > 0)
+ out_addline_outfile(out);
+
+ g_free(root);
+}
+
+static void
+print_glade_widget(Method *m, Variable *v)
+{
+ char *root;
+ char *cast;
+
+ if(!v->glade_widget)
+ return;
+
+ if(v->scope == PRIVATE_SCOPE)
+ root = g_strconcat(((FuncArg *)m->args->data)->name,
+ "->_priv", NULL);
+ else
+ root = g_strdup(((FuncArg *)m->args->data)->name);
+
+ cast = get_type(v->vtype, FALSE);
+ out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
+ root, v->id, cast, root, v->id);
+
+ g_free(root);
+}
+
+static void
+print_destructor (Variable *v)
+{
+ const char *root;
+
+ if(v->destructor == NULL)
+ return;
+
+ if(v->scope == PRIVATE_SCOPE)
+ root = "self->_priv";
+ else
+ root = "self";
+
+ if(v->destructor_simple) {
+ if(v->destructor_line > 0)
+ out_addline_infile(out, v->destructor_line);
+
+ if (for_cpp) {
+ out_printf(out, "\tif(%s->%s) { "
+ "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
+ "%s->%s = NULL; }\n",
+ root, v->id, v->destructor, root, v->id,
+ root, v->id);
+ } else {
+ out_printf(out, "\tif(%s->%s) { "
+ "%s ((gpointer) %s->%s); "
+ "%s->%s = NULL; }\n",
+ root, v->id, v->destructor, root, v->id,
+ root, v->id);
+ }
+
+ if(v->destructor_line > 0)
+ out_addline_outfile(out);
+ } else {
+ out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
+ out_printf(out, "#define VAR %s\n", v->id);
+ out_printf(out, "\t{\n");
+ if(v->destructor_line > 0)
+ out_addline_infile(out, v->destructor_line);
+
+ out_printf(out, "\t%s}\n", v->destructor);
+
+ if(v->destructor_line > 0)
+ out_addline_outfile(out);
+ out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
+ v->id, v->id);
+ out_printf(out, "#undef VAR\n");
+ out_printf(out, "#undef %s\n", v->id);
+ }
+}
+
+static void
+add_constructor (Class *c)
+{
+ out_printf(out, "\nstatic GObject *\n"
+ "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
+ "{\n");
+ out_printf(out,
+ "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
+ c->otype);
+
+ out_printf(out, "\tGObject *obj_self;\n");
+ out_printf(out, "\t%s *self;\n", typebase);
+
+ out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
+ out_printf(out, "\tself = %s (obj_self);\n", macrobase);
+
+ if (user_constructor->line_no > 0)
+ out_addline_infile (out, user_constructor->line_no);
+ out_printf (out, "\t%s_constructor (self);\n", funcbase);
+ if (user_constructor->line_no > 0)
+ out_addline_outfile (out);
+
+ out_printf(out, "\treturn obj_self;\n");
+ out_printf(out, "}\n"
+ "#undef __GOB_FUNCTION__\n\n");
+}
+
+static void
+print_unreftors (Class *c)
+{
+ GList *li;
+ for(li = ((Class *)class)->nodes;
+ li != NULL;
+ li = li->next) {
+ Node *n = li->data;
+ Variable *v = (Variable *)n;
+ if (n->type == VARIABLE_NODE &&
+ v->scope != CLASS_SCOPE &&
+ v->destructor_unref)
+ print_destructor (v);
+ }
+}
+
+static void
+add_dispose (Class *c)
+{
+ out_printf(out, "\nstatic void\n"
+ "___dispose (GObject *obj_self)\n"
+ "{\n");
+ out_printf(out,
+ "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
+ c->otype);
+
+ if (unreftors > 0 || user_dispose_method != NULL) {
+ out_printf (out, "\t%s *self%s = %s (obj_self);\n",
+ typebase,
+ ! no_gnu ? " G_GNUC_UNUSED" : "",
+ macrobase);
+ }
+
+ if (dispose_handler != NULL) {
+ if (unreftors > 0) {
+ print_unreftors (c);
+ }
+
+ /* so we get possible bad argument warning */
+ if (dispose_handler->line_no > 0)
+ out_addline_infile (out, dispose_handler->line_no);
+ out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
+ (guint)dispose_handler->unique_id, funcbase);
+ if (dispose_handler->line_no > 0)
+ out_addline_outfile (out);
+ } else {
+ if (user_dispose_method != NULL) {
+ if (user_dispose_method->line_no > 0)
+ out_addline_infile (out, user_dispose_method->line_no);
+ out_printf (out, "\t%s_dispose (self);\n", funcbase);
+ if (user_dispose_method->line_no > 0)
+ out_addline_outfile (out);
+ }
+
+ if (unreftors > 0) {
+ print_unreftors (c);
+ }
+
+ out_printf (out,
+ "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
+ "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
+ }
+
+ out_printf(out, "}\n"
+ "#undef __GOB_FUNCTION__\n\n");
+}
+
+static void
+print_destructors (Class *c)
+{
+ GList *li;
+ for (li = ((Class *)class)->nodes;
+ li != NULL;
+ li = li->next) {
+ Node *n = li->data;
+ Variable *v = (Variable *)n;
+ if (n->type == VARIABLE_NODE &&
+ v->scope != CLASS_SCOPE &&
+ ! v->destructor_unref)
+ print_destructor (v);
+ }
+}
+
+static void
+add_finalize (Class *c)
+{
+ out_printf(out,
+ "\nstatic void\n"
+ "___finalize(GObject *obj_self)\n"
+ "{\n");
+ out_printf(out,
+ "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
+ c->otype);
+
+ if (privates > 0 ||
+ destructors > 0 ||
+ user_finalize_method != NULL) {
+ const char *unused = "";
+ if ( ! no_gnu)
+ unused = " G_GNUC_UNUSED";
+ out_printf(out, "\t%s *self%s = %s (obj_self);\n",
+ typebase, unused, macrobase);
+ }
+ if (privates > 0) {
+ const char *unused = "";
+ if ( ! no_gnu)
+ unused = " G_GNUC_UNUSED";
+ out_printf(out, "\tgpointer priv%s = self->_priv;\n",
+ unused);
+ }
+
+ if(finalize_handler) {
+ if (destructors > 0) {
+ print_destructors (c);
+ }
+
+ /* so we get possible bad argument warning */
+ if(finalize_handler->line_no > 0)
+ out_addline_infile(out, finalize_handler->line_no);
+ out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
+ (guint)finalize_handler->unique_id, funcbase);
+ if(finalize_handler->line_no > 0)
+ out_addline_outfile(out);
+ } else {
+ if (user_finalize_method != NULL) {
+ if (user_finalize_method->line_no > 0)
+ out_addline_infile (out, user_finalize_method->line_no);
+ out_printf (out, "\t%s_finalize (self);\n", funcbase);
+ if (user_finalize_method->line_no > 0)
+ out_addline_outfile (out);
+ }
+
+ if (destructors > 0) {
+ print_destructors (c);
+ }
+
+ out_printf(out,
+ "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
+ "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
+ }
+
+ out_printf(out, "}\n"
+ "#undef __GOB_FUNCTION__\n\n");
+}
+
+static void
+make_bonobo_object_epv (Class *c, const char *classname)
+{
+ GList *li;
+ gboolean added_line = FALSE;
+
+ for (li = c->nodes; li != NULL; li = li->next) {
+ Node *n = li->data;
+ Method *m = (Method *)n;
+ if(n->type != METHOD_NODE ||
+ m->method == OVERRIDE_METHOD)
+ continue;
+
+ if (m->bonobo_object_func) {
+ if(m->line_no > 0) {
+ out_addline_infile(out, m->line_no);
+ added_line = TRUE;
+ } else if (m->line_no == 0 &&
+ added_line) {
+ out_addline_outfile(out);
+ added_line = FALSE;
+ }
+ out_printf (out, "\t%s->_epv.%s = self_%s;\n",
+ classname, m->id, m->id);
+ }
+ }
+ if (added_line)
+ out_addline_outfile(out);
+}
+
+static void add_class_private(Class *c, Method *m)
+{
+ const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
+
+ if (!privates)
+ return;
+
+ out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
+ " || !defined(G_ADD_PRIVATE%s)\n"
+ "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
+ "#endif\n",
+ dynamic, dynamic,
+ ((FuncArg *)m->args->data)->name, typebase);
+}
+
+static void get_instance_private(Class *c, Method *m)
+{
+ const char *self = ((FuncArg *)m->args->data)->name;
+ const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
+
+ if (!privates) {
+ if (always_private_struct) {
+ out_printf(out, "\t%s->_priv = NULL;\n", self);
+ }
+
+ return;
+ }
+
+ out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
+ "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
+ " && defined(G_ADD_PRIVATE%s)\n"
+ "\t\t%s_get_instance_private(%s);\n"
+ "#else\n"
+ "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
+ "\t\t\t( %s\n"
+ "\t\t\t, %s\n"
+ "\t\t\t, %sPrivate\n"
+ "\t\t\t);\n"
+ "#endif\n",
+ self, typebase,
+ dynamic, dynamic,
+ funcbase, self,
+ self, macrotype, typebase);
+}
+
+static void
+add_inits(Class *c)
+{
+ const char *unused = "";
+ GList *li;
+
+ if ( ! no_gnu)
+ unused = " G_GNUC_UNUSED";
+
+ for(li=c->nodes;li;li=g_list_next(li)) {
+ Node *n = li->data;
+ Method *m;
+