+ }
+
+ 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_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);
+ if (privates > 0) {
+ out_printf(out, "\t%s->_priv = "
+ "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
+ ((FuncArg *)m->args->data)->name,
+ ((FuncArg *)m->args->data)->name,
+ macrotype,
+ typebase);
+ } else if(always_private_struct) {
+ out_printf(out, "\t%s->_priv = NULL;\n",
+ ((FuncArg *)m->args->data)->name);
+ }
+ 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);
+
+ if (privates > 0)
+ out_printf (out,
+ "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
+ ((FuncArg *)m->args->data)->name,
+ typebase);
+
+ 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");
+ }