+ 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;
+
+ if(n->type != METHOD_NODE)
+ continue;
+ m = (Method *)n;
+ if(m->method == INIT_METHOD) {
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ print_method(out, "static ", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, FALSE, TRUE, TRUE,
+ FALSE);
+ out_printf(out, "{\n");
+ if(m->line_no > 0)
+ out_addline_outfile(out);
+ out_printf(out,
+ "#define __GOB_FUNCTION__ \"%s::init\"\n",
+ c->otype);
+
+ get_instance_private(c, m);
+
+ if(initializers > 0) {
+ 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)
+ continue;
+ print_initializer(m, v);
+ }
+ }
+ if(glade_widgets > 0) {
+ 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)
+ continue;
+ print_glade_widget(m, v);
+ }
+ }
+ } else if(m->method == CLASS_INIT_METHOD) {
+ gboolean did_base_obj = FALSE;
+
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ print_method(out, "static ", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, FALSE, TRUE, TRUE,
+ FALSE);
+ out_printf(out, "{\n");
+ if(m->line_no > 0)
+ out_addline_outfile(out);
+ out_printf(out,
+ "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
+ c->otype);
+ if (set_properties > 0 ||
+ get_properties > 0 ||
+ signals > 0 ||
+ need_constructor ||
+ need_dispose ||
+ need_finalize) {
+ out_printf(out,
+ "\tGObjectClass *"
+ "g_object_class%s = "
+ "(GObjectClass*) %s;\n",
+ unused,
+ ((FuncArg *)m->args->data)->name);
+ did_base_obj = TRUE;
+ }
+
+ if (overrides > 0)
+ add_overrides (c,
+ ((FuncArg *)m->args->data)->name,
+ did_base_obj);
+
+ add_class_private(c, m);
+
+ if (initializers > 0) {
+ 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)
+ print_initializer(m, v);
+ }
+ }
+
+ out_printf(out, "\n\tparent_class = ");
+ if(for_cpp)
+ out_printf(out, "(%sClass *)", ptypebase);
+ out_printf(out, "g_type_class_ref (%s);\n",
+ pmacrotype);
+
+ if(signals > 0)
+ add_signals(c);
+
+ set_def_handlers(c, ((FuncArg *)m->args->data)->name);
+
+ /* if there are no handlers for these things, we
+ * need to set them up here */
+ if(need_constructor)
+ out_printf(out, "\tg_object_class->constructor "
+ "= ___constructor;\n");
+ if(need_dispose && !dispose_handler)
+ out_printf(out, "\tg_object_class->dispose "
+ "= ___dispose;\n");
+ if(need_finalize && !finalize_handler)
+ out_printf(out, "\tg_object_class->finalize = "
+ "___finalize;\n");
+
+ if(get_properties > 0 || set_properties > 0)
+ make_arguments(c);
+
+ if (c->bonobo_object_class != NULL) {
+ make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
+ }
+ } else
+ continue;
+
+ if(m->cbuf) {
+ out_printf(out, " {\n");
+ out_addline_infile(out, m->ccode_line);
+ out_printf(out, "%s\n", m->cbuf);
+ out_addline_outfile(out);
+ out_printf(out, " }\n");
+ }
+ out_printf(out, "}\n"
+ "#undef __GOB_FUNCTION__\n");
+ }
+}
+
+static void
+add_argument (Argument *a, gboolean is_set)
+{
+ char *s;
+ char *cbuf;
+ char *the_type_lower;
+ int line_no;
+
+ if(is_set) {
+ cbuf = a->set;
+ line_no = a->set_line;
+ } else {
+ cbuf = a->get;
+ line_no = a->get_line;
+ }
+ if (cbuf == NULL)
+ return;
+ s = g_strdup(a->name);
+ gob_strup (s);
+ out_printf(out, "\tcase PROP_%s:\n\t{", s);
+
+ the_type_lower = g_strdup (a->gtktype);
+ gob_strdown (the_type_lower);
+
+ /* HACK because there is no g_value_set/get for unichar */
+ if (strcmp (the_type_lower, "unichar") == 0) {
+ g_free (the_type_lower);
+ the_type_lower = g_strdup ("uint");
+ }
+
+ if (is_set) {
+ char *cast;
+ const char *unused = "";
+
+ if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
+ unused = " G_GNUC_UNUSED";
+ }
+
+ if (a->atype != NULL &&
+ /* gcc -Wbad-function-cast is wanking stupid, moronic
+ and otherwise evil so we should just use a (gint)
+ or (guint) cast, not the specific type cast */
+ (for_cpp ||
+ (strcmp (a->gtktype, "ENUM") != 0 &&
+ strcmp (a->gtktype, "FLAGS") != 0)))
+ cast = get_type (a->atype, TRUE);
+ else
+ cast = g_strdup (get_cast (a->gtktype, FALSE));
+
+ out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
+ cast, unused, cast, the_type_lower);
+
+ g_free (cast);
+ } else if ( ! is_set) {
+ char *cast;
+
+ if (a->atype != NULL)
+ cast = get_type (a->atype, TRUE);
+ else
+ cast = g_strdup (get_cast (a->gtktype, FALSE));
+ out_printf (out, "\t%s ARG;\n"
+ "\tmemset (&ARG, 0, sizeof (%s));\n",
+ cast, cast);
+
+ g_free(cast);
+ }
+ g_free (s);
+ out_printf(out, "\t\t{\n");
+ if (line_no > 0)
+ out_addline_infile (out, line_no);
+ out_printf (out, "%s\n", cbuf);
+ if (line_no > 0)
+ out_addline_outfile (out);
+ out_printf (out, "\t\t}\n");
+ if ( ! is_set) {
+ if (strcmp (a->gtktype, "OBJECT") == 0)
+ out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
+ the_type_lower);
+ else
+ out_printf (out, "\t\t"
+ "g_value_set_%s (VAL, ARG);\n",
+ the_type_lower);
+ }
+ g_free (the_type_lower);
+
+ if (is_set &&
+ (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
+ out_printf (out, "\t\tif (&ARG) break;\n");
+ }
+
+ out_printf (out, "\t\tbreak;\n");
+
+ out_printf (out, "\t}\n");
+}
+
+static void
+add_property (Property *p, gboolean is_set)
+{
+ const char *cbuf;
+ char *the_type_lower;
+ char *name_upper;
+ int line_no;
+
+ if (is_set) {
+ cbuf = p->set;
+ line_no = p->set_line;
+ } else {
+ cbuf = p->get;
+ line_no = p->get_line;
+ }
+ if (cbuf == NULL)
+ return;
+
+ name_upper = g_strdup (p->name);
+ gob_strup (name_upper);
+ the_type_lower = g_strdup (p->gtktype);
+ gob_strdown (the_type_lower);
+
+ out_printf (out, "\tcase PROP_%s:\n", name_upper);
+
+ out_printf(out, "\t\t{\n");
+ if (line_no > 0)
+ out_addline_infile (out, line_no);
+ out_printf (out, "%s\n", cbuf);
+ if (line_no > 0)
+ out_addline_outfile (out);
+ out_printf (out, "\t\t}\n");
+
+ g_free (name_upper);
+ g_free (the_type_lower);
+
+ out_printf (out, "\t\tbreak;\n");
+}
+
+static void
+add_getset_arg(Class *c, gboolean is_set)
+{
+ GList *li;
+ const char *unused = "";
+ const char *hack_unused = "";
+
+ if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
+ unused = " G_GNUC_UNUSED";
+ } else {
+ hack_unused = "if (&VAL || &pspec) break;\n\t\t";
+ }
+
+ out_printf(out, "\nstatic void\n"
+ "___object_%s_property (GObject *object,\n"
+ "\tguint property_id,\n"
+ "\t%sGValue *VAL%s,\n"
+ "\tGParamSpec *pspec%s)\n"
+ "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
+ "{\n"
+ "\t%s *self%s;\n\n"
+ "\tself = %s (object);\n\n"
+ "\tswitch (property_id) {\n",
+ is_set ? "set" : "get",
+ is_set ? "const " : "",
+ unused,
+ unused,
+ c->otype,
+ is_set ? "set" : "get",
+ typebase,
+ unused,
+ macrobase);
+
+ for (li = c->nodes; li != NULL; li = li->next) {
+ Node *n = li->data;
+ if (n->type == PROPERTY_NODE)
+ add_property ((Property *)n, is_set);
+ else if (n->type == ARGUMENT_NODE)
+ add_argument ((Argument *)n, is_set);
+ }
+ out_printf (out, "\tdefault:\n"
+ "/* Apparently in g++ this is needed, glib is b0rk */\n"
+ "#ifndef __PRETTY_FUNCTION__\n"
+ "# undef G_STRLOC\n"
+ "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
+ "#endif\n"
+ "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
+ "\t\t%sbreak;\n\t}\n"
+ "}\n"
+ "#undef __GOB_FUNCTION__\n", hack_unused);
+}
+
+static void
+print_checks (Method *m, FuncArg *fa)
+{
+ GList *li;
+ gboolean is_void;
+ gboolean checked_null = FALSE;
+ is_void = (strcmp(m->mtype->name, "void")==0 &&
+ m->mtype->pointer == NULL);
+
+ for(li = fa->checks; li != NULL; li = li->next) {
+ Check *ch = li->data;
+ char *s;
+ /* point to the method prot in .gob for failed checks */
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ if(is_void)
+ out_printf(out, "\tg_return_if_fail (");
+ else
+ out_printf(out, "\tg_return_val_if_fail (");
+ switch(ch->chtype) {
+ case NULL_CHECK:
+ out_printf(out, "%s != NULL", fa->name);
+ checked_null = TRUE;
+ break;
+ case TYPE_CHECK:
+ s = make_pre_macro(fa->atype->name, "IS");
+ if(checked_null)
+ out_printf(out, "%s (%s)", s, fa->name);
+ else
+ /* if not check null, null may be valid */
+ out_printf(out, "!(%s) || %s (%s)", fa->name,
+ s, fa->name);
+ g_free(s);
+ break;
+ case LT_CHECK:
+ out_printf(out, "%s < %s", fa->name, ch->number);
+ break;
+ case GT_CHECK:
+ out_printf(out, "%s > %s", fa->name, ch->number);
+ break;
+ case LE_CHECK:
+ out_printf(out, "%s <= %s", fa->name, ch->number);
+ break;
+ case GE_CHECK:
+ out_printf(out, "%s >= %s", fa->name, ch->number);
+ break;
+ case EQ_CHECK:
+ out_printf(out, "%s == %s", fa->name, ch->number);
+ break;
+ case NE_CHECK:
+ out_printf(out, "%s != %s", fa->name, ch->number);
+ break;
+ }
+ if(is_void)
+ out_printf(out, ");\n");
+ else {
+ out_printf(out, ", (");
+ print_type(out, m->mtype, TRUE);
+ out_printf(out, ")%s);\n",
+ m->onerror?m->onerror:"0");
+ }
+ }
+}
+
+static void
+print_preconditions(Method *m)
+{
+ GList *li;
+
+ for(li=m->args;li;li=g_list_next(li)) {
+ FuncArg *fa = li->data;
+ if(fa->checks)
+ print_checks(m, fa);
+ }
+ if(m->line_no>0)
+ out_addline_outfile(out);
+}
+
+static void
+print_method_body (Method *m, gboolean pre, gboolean unused_self)
+{
+ out_printf(out, "{\n");
+ if (m->line_no > 0)
+ out_addline_outfile(out);
+ out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
+ ((Class *)class)->otype,
+ m->id);
+ if (pre)
+ print_preconditions(m);
+
+ if ( ! pre &&
+ unused_self &&
+ (no_gnu || for_cpp) &&
+ m->args != NULL &&
+ ((FuncArg *)(m->args->data))->name != NULL &&
+ strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
+ out_printf (out, "\tif (&self) { ; }\n");
+ }
+
+ /* Note: the trailing }'s are on one line, this is so
+ that we get the no return warning correctly and point to
+ the correct line in the .gob file, yes this is slightly
+ ugly in the .c file, but that is not supposed to be
+ human readable anyway. */
+ if(m->cbuf) {
+ out_printf(out, "{\n");
+ if(m->ccode_line>0)
+ out_addline_infile(out, m->ccode_line);
+ out_printf(out, "\t%s}", m->cbuf);
+ }
+
+ /* Note, there is no \n between the last } and this } so that
+ * errors/warnings reported on the end of the body get pointed to the
+ * right line in the .gob source */
+ out_printf(out, "}\n");
+
+ if(m->cbuf)
+ out_addline_outfile(out);
+ out_printf(out, "#undef __GOB_FUNCTION__\n");
+}
+
+static void
+put_signal_args (Method *m)
+{
+ GList *li;
+ GList *ali;
+ int i;
+
+ if (m->args->next == NULL)
+ return;
+
+ for (ali = m->gtktypes->next, li = m->args->next, i = 1;
+ li != NULL && ali != NULL;
+ li = li->next, ali = ali->next, i++) {
+ FuncArg *fa = li->data;
+ char *str = ali->data;
+ char *cast = g_strdup (get_cast (str, FALSE));
+ /* FIXME: This code is so fucking ugly it hurts */
+ gboolean do_static =
+ (strcmp (str, "STRING") == 0 ||
+ strcmp (str, "BOXED") == 0 ||
+ strncmp (str, "BOXED_", 6) == 0);
+ char *set_func;
+ char *t;
+
+ if (cast == NULL) {
+ cast = get_type (fa->atype, TRUE);
+ }
+ /* we should have already proved before that
+ the we know all the types */
+ g_assert (cast != NULL);
+
+ if (strncmp (str, "BOXED_", 6) == 0)
+ t = g_strdup (&(str[6]));
+ else
+ t = g_strconcat ("G_TYPE_", str, NULL);
+
+ out_printf (out,
+ "\t___param_values[%d].g_type = 0;\n"
+ "\tg_value_init (&___param_values[%d], %s);\n",
+ i, i, t);
+ g_free (t);
+
+ if (strcmp (str, "UNICHAR") == 0)
+ /* hack because glib is braindamaged */
+ set_func = g_strdup ("g_value_set_uint");
+ else if (strncmp (str, "BOXED_", 6) == 0)
+ set_func = g_strdup ("g_value_set_static_boxed");
+ else
+ set_func = g_strdup_printf ("g_value_set%s_%s",
+ do_static ? "_static" : "",
+ str);
+ gob_strdown (set_func);
+
+ out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
+ set_func, i, cast, fa->name);
+
+ g_free (set_func);
+ g_free (cast);
+ }
+}
+
+static void
+clear_signal_args (Method *m)
+{
+ GList *li;
+ int i;
+
+ out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
+
+ if (m->args->next == NULL)
+ return;
+
+ for (li = m->args->next, i = 1;
+ li != NULL;
+ li = li->next, i++) {
+ out_printf (out,
+ "\tg_value_unset (&___param_values[%d]);\n", i);
+ }
+}
+
+static char *
+get_arg_names_for_macro (Method *m)
+{
+ const char *sep;
+ GList *li;
+ GString *gs = g_string_new(NULL);
+ sep = "";
+ for(li=m->args;li;li=g_list_next(li)) {
+ FuncArg *arg = li->data;
+ g_string_append_printf(gs, "%s___%s", sep, arg->name);
+ sep = ",";
+ }
+ 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);
+}