+ out_printf(out, "\t%s->%s = NULL;\n",
+ oname, get_real_id(m->id));
+ }
+ }
+ if(set_line)
+ out_addline_outfile(out);
+}
+
+static void
+make_arguments(Class *c)
+{
+ GList *li;
+ char *argflags[] = {
+ "CONSTRUCT",
+ "CONSTRUCT_ONLY",
+ "CHILD_ARG",
+ "MASK",
+ NULL
+ };
+
+ out_printf(out, "\n");
+ for(li=c->nodes;li;li=g_list_next(li)) {
+ Node *n = li->data;
+ Argument *a;
+ GString *flags;
+ GList *l;
+ char *s;
+ if(n->type != ARGUMENT_NODE)
+ continue;
+
+ a = (Argument *)n;
+
+ if(a->get && a->set)
+ flags = g_string_new("GTK_ARG_READWRITE");
+ else if(a->get)
+ flags = g_string_new("GTK_ARG_READABLE");
+ else
+ flags = g_string_new("GTK_ARG_WRITABLE");
+
+ g_assert(a->get || a->set);
+
+ for(l=a->flags;l;l=g_list_next(l)) {
+ char *flag = l->data;
+ int i;
+ if(strcmp(flag, "READWRITE")==0 ||
+ strcmp(flag, "READABLE")==0 ||
+ strcmp(flag, "WRITABLE")==0) {
+ error_print(GOB_WARN, a->line_no,
+ "READWRITE, READABLE and "
+ "WRITABLE argument flags are "
+ "set automatically");
+ continue;
+ }
+ for(i = 0; argflags[i]; i++) {
+ if(strcmp(argflags[i], flag)==0)
+ break;
+ }
+ /* if we haven't found it in our list */
+ if( ! argflags[i]) {
+ error_printf(GOB_WARN, a->line_no,
+ "Unknown flag '%s' used, "
+ "perhaps it was misspelled", flag);
+ }
+ g_string_sprintfa(flags, " | GTK_ARG_%s", flag);
+ }
+
+ s = g_strdup(a->name);
+ g_strup(s);
+ out_printf(out, "\tgtk_object_add_arg_type(\"%s::%s\",\n"
+ "\t\tGTK_TYPE_%s,\n"
+ "\t\t%s,\n"
+ "\t\tARG_%s);\n",
+ typebase, a->name, a->gtktype, flags->str, s);
+ g_free(s);
+ g_string_free(flags, TRUE);
+ }
+
+ out_printf(out, "\n");
+ if(get_arguments > 0)
+ out_printf(out, "\tgtk_object_class->get_arg = ___object_get_arg;\n");
+ if(set_arguments > 0)
+ out_printf(out, "\tgtk_object_class->set_arg = ___object_set_arg;\n");
+}
+
+static void
+print_initializer(Method *m, Variable *v)
+{
+ char *root;
+
+ 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);
+
+ out_printf(out, "\t%s->%s = %s;\n",
+ root, v->id, v->initializer);
+
+ if(v->initializer_line > 0)
+ out_addline_outfile(out);
+
+ g_free(root);
+}
+
+static void
+print_destructor(Variable *v)
+{
+ 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);
+
+ out_printf(out, "\tif(%s->%s) { "
+ "((*(void (*)(void *))%s)) (%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 VAR (%s->%s)\n", root, 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(&VAR, 0, sizeof(VAR));\n");
+ out_printf(out, "#undef VAR\n");
+ }
+}
+
+static void
+add_destroy(Class *c)
+{
+ out_printf(out, "\nstatic void\n"
+ "___destroy(GtkObject *obj_self)\n"
+ "{\n");
+ out_printf(out,
+ "#define __GOB_FUNCTION__ \"%s::destroy\"\n",
+ c->otype);
+
+ if(destructors > 0) {
+ out_printf(out, "\t%s *self = %s (obj_self);\n",
+ typebase, macrobase);
+ }
+
+ if(destroy_handler) {
+ /* so we get possible bad argument warning */
+ if(destroy_handler->line_no > 0)
+ out_addline_infile(out, destroy_handler->line_no);
+ out_printf(out, "\t___%x_%s_destroy(obj_self);\n",
+ (guint)destroy_handler->unique_id, funcbase);
+ if(destroy_handler->line_no > 0)
+ out_addline_outfile(out);
+ } else {
+ out_printf(out,
+ "\tif(GTK_OBJECT_CLASS(parent_class)->destroy) \\\n"
+ "\t\t(* GTK_OBJECT_CLASS(parent_class)->destroy)(obj_self);\n");
+ }
+
+ if(destructors > 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_destructor(v);
+ }
+ }
+
+ out_printf(out, "\treturn;\n");
+ if(destructors > 0)
+ out_printf(out, "\tself = NULL;\n");
+ out_printf(out, "}\n"
+ "#undef __GOB_FUNCTION__\n\n");
+}
+
+static void
+add_finalize(Class *c)
+{
+ /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
+ out_printf(out,
+ "\n#ifdef G_OBJECT_CLASS\n"
+ "static void\n"
+ "___finalize(GObject *obj_self)\n"
+ "#else /* !G_OBJECT_CLASS */\n"
+ "static void\n"
+ "___finalize(GtkObject *obj_self)\n"
+ "#endif /* G_OBJECT_CLASS */\n"
+ "{\n");
+ out_printf(out,
+ "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
+ c->otype);
+
+ if(privates > 0) {
+ out_printf(out, "\t%s *self = %s (obj_self);\n",
+ typebase, macrobase);
+ out_printf(out, "\tgpointer priv = self->_priv;\n");
+ }
+
+ if(finalize_handler) {
+ /* 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 {
+ /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
+ out_printf(out,
+ "#ifdef G_OBJECT_CLASS\n"
+ "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
+ "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
+ "#else /* !G_OBJECT_CLASS */\n"
+ "\tif(GTK_OBJECT_CLASS(parent_class)->finalize) \\\n"
+ "\t\t(* GTK_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
+ "#endif /* G_OBJECT_CLASS */\n");
+ }
+
+ if(privates > 0) {
+ out_printf(out, "\tg_free(priv);\n");
+ }
+
+ out_printf(out, "}\n"
+ "#undef __GOB_FUNCTION__\n\n");
+}
+
+static void
+make_bonobo_x_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_x_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 = %s;\n",
+ classname, m->id, m->id);
+ }
+ }
+ if (added_line)
+ out_addline_outfile(out);
+}
+
+static void
+add_inits(Class *c)
+{
+ GList *li;
+ for(li=c->nodes;li;li=g_list_next(li)) {
+ Node *n = li->data;
+ Method *m;
+
+ gboolean add_unused_class = FALSE;
+
+ 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, TRUE);
+ if(m->line_no > 0)
+ out_addline_outfile(out);
+ out_printf(out, "{\n"
+ "#define __GOB_FUNCTION__ \"%s::init\"\n",
+ c->otype);
+ if(privates > 0) {
+ out_printf(out, "\t%s->_priv = "
+ "g_new0 (%sPrivate, 1);\n",
+ ((FuncArg *)m->args->data)->name,
+ 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);
+ }
+ }
+ } 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, TRUE);
+ if(m->line_no > 0)
+ out_addline_outfile(out);
+ out_printf(out, "{\n"
+ "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
+ c->otype);
+ if(signals > 0 ||
+ set_arguments > 0 ||
+ get_arguments > 0 ||
+ need_destroy ||
+ need_finalize) {
+ add_unused_class = TRUE;
+ out_printf(out,
+ "\tGtkObjectClass *"
+ "gtk_object_class = "
+ "(GtkObjectClass*) %s;\n",
+ ((FuncArg *)m->args->data)->name);
+ out_printf(out,
+ "#ifdef G_OBJECT_CLASS\n"
+ "\tGObjectClass *"
+ "g_object_class = "
+ "(GObjectClass*) %s;\n"
+ "#endif /* G_OBJECT_CLASS */\n",
+ ((FuncArg *)m->args->data)->name);
+ did_base_obj = TRUE;
+ }
+
+ if(overrides > 0)
+ add_overrides(c,
+ ((FuncArg *)m->args->data)->name,
+ did_base_obj);
+
+ 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, "gtk_type_class (%s_get_type ());\n",
+ pfuncbase);
+
+ 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_destroy && !destroy_handler)
+ out_printf(out, "\tgtk_object_class->destroy "
+ "= ___destroy;\n");
+ if(need_finalize && !finalize_handler)
+ out_printf(out,
+ "#ifdef G_OBJECT_CLASS\n"
+ "\tg_object_class->finalize = ___finalize;\n"
+ "#else /* !G_OBJECT_CLASS */\n"
+ "\tgtk_object_class->finalize = ___finalize;\n"
+ "#endif /* G_OBJECT_CLASS */\n");
+
+ if(get_arguments > 0 || set_arguments > 0)
+ make_arguments(c);
+
+ if (c->bonobo_x_class != NULL) {
+ make_bonobo_x_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, "\treturn;\n");
+ out_printf(out,
+ "\t%s = NULL;\n",
+ ((FuncArg *)m->args->data)->name);
+ if(add_unused_class) {
+ out_printf(out,
+ "\tgtk_object_class = NULL;\n"
+ "#ifdef G_OBJECT_CLASS\n"
+ "\tg_object_class = NULL;\n"
+ "#endif /* G_OBJECT_CLASS */\n");
+ }
+ out_printf(out, "}\n"
+ "#undef __GOB_FUNCTION__\n");
+ }
+}
+
+static void
+add_getset_arg(Class *c, gboolean is_set)
+{
+ GList *li;
+ out_printf(out, "\nstatic void\n"
+ "___object_%s_arg (GtkObject *object,\n"
+ "\tGtkArg *arg,\n"
+ "\tguint arg_id)\n"
+ "#define __GOB_FUNCTION__ \"%s::%s_arg\"\n"
+ "{\n"
+ "\t%s *self;\n\n"
+ "\tself = %s (object);\n\n"
+ "\tswitch (arg_id) {\n",
+ is_set ? "set" : "get",
+ c->otype, is_set ? "set" : "get",
+ typebase, macrobase);
+
+ for(li=c->nodes;li;li=g_list_next(li)) {
+ Node *n = li->data;
+ Argument *a;
+ char *s;
+ char *cbuf;
+ int line_no;
+ if(n->type != ARGUMENT_NODE)
+ continue;
+ a = (Argument *)n;
+ if(is_set) {
+ cbuf = a->set;
+ line_no = a->set_line;
+ } else {
+ cbuf = a->get;
+ line_no = a->get_line;
+ }
+ if(!cbuf)
+ continue;
+ s = g_strdup(a->name);
+ g_strup(s);
+ out_printf(out, "\tcase ARG_%s:\n", s);
+ if(is_set && a->atype) {
+ char *cast = get_type(a->atype, TRUE);
+ if(no_gnu || for_cpp) {
+ out_printf(out, "#define ARG "
+ "((%s)GTK_VALUE_%s(*arg))\n",
+ cast, a->gtktype);
+ } else {
+ out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
+ if(strcmp(a->gtktype, "OBJECT")==0) {
+ out_printf(out, "#define ARG "
+ "({%s foo = "
+ "GTK_VALUE_POINTER(*arg); "
+ "foo; })\n",
+ cast);
+ } else {
+ out_printf(out, "#define ARG "
+ "({%s foo = "
+ "GTK_VALUE_%s(*arg); "
+ "foo; })\n",
+ cast, a->gtktype);
+ }
+ out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
+ out_printf(out, "#define ARG "
+ "((%s)GTK_VALUE_%s(*arg))\n",
+ cast, a->gtktype);
+ out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
+ }
+ out_printf(out, "\t\t{\n");
+ g_free(cast);
+ } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
+ out_printf(out,
+ "#define ARG (GTK_VALUE_POINTER(*arg))\n"
+ "\t\t{\n");
+ } else {
+ out_printf(out,
+ "#define ARG (GTK_VALUE_%s(*arg))\n"
+ "\t\t{\n",
+ a->gtktype);
+ }
+ g_free(s);
+ 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\t\tbreak;\n"
+ "#undef ARG\n");
+ }
+ out_printf(out, "\tdefault:\n\t\tbreak;\n\t}\n"
+ "\treturn;\n\tself = NULL;\n\targ = NULL;\n}\n"
+ "#undef __GOB_FUNCTION__\n");
+}
+
+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; li = g_list_next(li)) {
+ 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, int pre)
+{
+ if (m->line_no > 0)
+ out_addline_outfile(out);
+ out_printf(out, "{\n"
+ "#define __GOB_FUNCTION__ \"%s::%s\"\n",
+ ((Class *)class)->otype,
+ get_real_id(m->id));
+ if(pre)
+ print_preconditions(m);
+
+ /* 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;
+ for(ali = m->gtktypes->next, li=m->args->next;
+ li && ali;
+ li=li->next, ali=ali->next) {
+ FuncArg *fa = li->data;
+ const char *cast = get_cast(ali->data, FALSE);
+ /* we should have already proved before that
+ the we know all the types */
+ g_assert(cast);
+
+ out_printf(out, ",\n\t\t(%s)%s", cast,
+ fa->name);
+ }
+}
+
+static char *
+get_arg_names_for_macro(Method *m)
+{
+ char *p;
+ GList *li;
+ GString *gs = g_string_new(NULL);
+ p = "";
+ for(li=m->args;li;li=g_list_next(li)) {
+ FuncArg *arg = li->data;
+ g_string_sprintfa(gs, "%s___%s", p, arg->name);
+ p = ",";
+ }
+ p = gs->str;
+ g_string_free(gs, FALSE);
+ return p;
+}
+
+static void
+put_method(Method *m)
+{
+ char *s, *args, *doc;
+ gboolean is_void;
+ is_void = (strcmp(m->mtype->name, "void")==0 &&
+ m->mtype->pointer == NULL);
+ out_printf(out, "\n");
+ if(m->method != OVERRIDE_METHOD) {
+ doc = get_gtk_doc(m->id);
+ if(doc) {
+ out_printf(out, "%s", doc);
+ g_free(doc);
+ }
+ }
+ switch(m->method) {
+ case REGULAR_METHOD:
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ if(m->scope == PRIVATE_SCOPE)
+ print_method(out, "static ", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ else /* PUBLIC, PROTECTED */
+ print_method(out, "", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ print_method_body(m, TRUE);
+ /* the outfile line was added above */
+ break;
+ case SIGNAL_FIRST_METHOD:
+ case SIGNAL_LAST_METHOD:
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ if(m->scope == PRIVATE_SCOPE)
+ print_method(out, "static ", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ else /* PUBLIC, PROTECTED */
+ print_method(out, "", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ out_addline_outfile(out);
+ out_printf(out, "{\n");
+ s = g_strdup(get_real_id(m->id));
+ g_strup(s);
+ if(strcmp(m->mtype->name, "void") == 0 &&
+ m->mtype->pointer == NULL) {
+ print_preconditions(m);
+ if(((FuncArg *)m->args->data)->name)
+ out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
+ "\t\tobject_signals[%s_SIGNAL]",
+ ((FuncArg *)m->args->data)->name, s);
+ put_signal_args(m);
+ out_printf(out, ");\n}\n");
+ } else {
+ out_printf(out, "\t");
+ print_type(out, m->mtype, TRUE);
+ out_printf(out, "return_val = (");
+ print_type(out, m->mtype, TRUE);
+ if(m->defreturn)
+ out_printf(out, ")(%s);\n", m->defreturn);
+ else if(m->onerror)
+ out_printf(out, ")(%s);\n", m->onerror);
+ else
+ out_printf(out, ")(0);\n");
+ print_preconditions(m);
+ out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
+ "\t\tobject_signals[%s_SIGNAL]",
+ ((FuncArg *)m->args->data)->name, s);
+ put_signal_args(m);
+ out_printf(out, ",\n\t\t&return_val);\n"
+ "\treturn return_val;\n}\n");
+ }
+
+ if(!m->cbuf)
+ break;
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ print_method(out, "static ", "\n___real_", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ print_method_body(m, FALSE);
+ /* the outfile line was added above */
+ break;
+ case VIRTUAL_METHOD:
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ if(m->scope==PRIVATE_SCOPE)
+ print_method(out, "static ", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ else /* PUBLIC, PROTECTED */
+ print_method(out, "", "\n", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ out_addline_outfile(out);
+ out_printf(out, "{\n"
+ "\t%sClass *klass;\n", typebase);
+ print_preconditions(m);
+ out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
+ "\tif(klass->%s)\n",
+ macrobase, ((FuncArg *)m->args->data)->name,
+ get_real_id(m->id));
+ if(strcmp(m->mtype->name, "void") == 0 &&
+ m->mtype->pointer == NULL) {
+ GList *li;
+ out_printf(out, "\t\t(*klass->%s)(%s",
+ get_real_id(m->id),
+ ((FuncArg *)m->args->data)->name);
+ for(li=m->args->next;li;li=g_list_next(li)) {
+ FuncArg *fa = li->data;
+ out_printf(out, ",%s", fa->name);
+ }
+ out_printf(out, ");\n}\n");
+ } else {
+ GList *li;
+ out_printf(out, "\t\treturn (*klass->%s)(%s",
+ get_real_id(m->id),
+ ((FuncArg *)m->args->data)->name);
+ for(li=m->args->next;li;li=g_list_next(li)) {
+ FuncArg *fa = li->data;
+ out_printf(out, ",%s", fa->name);
+ }
+ out_printf(out, ");\n"
+ "\telse\n"
+ "\t\treturn (");
+ print_type(out, m->mtype, TRUE);
+ if(m->defreturn)
+ out_printf(out, ")(%s);\n}\n", m->defreturn);
+ else if(m->onerror)
+ out_printf(out, ")(%s);\n}\n", m->onerror);
+ else
+ out_printf(out, ")(0);\n}\n");
+ }
+
+ if(!m->cbuf)
+ break;
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ print_method(out, "static ", "\n___real_", "", " ", "", "\n",
+ m, FALSE, FALSE, TRUE);
+ print_method_body(m, FALSE);
+ /* the outfile line was added above */
+ break;
+ case OVERRIDE_METHOD:
+ if(!m->cbuf)
+ break;
+ if(m->line_no > 0)
+ out_addline_infile(out, m->line_no);
+ s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
+ print_method(out, "static ", s, "", " ", "", "\n",
+ m, FALSE, FALSE, FALSE);
+ g_free(s);
+ out_addline_outfile(out);
+ s = replace_sep(m->otype, '_');
+ g_strup(s);
+ args = get_arg_names_for_macro(m);
+ if(is_void) {
+ out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
+ "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
+ "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
+ args, s, get_real_id(m->id), s, get_real_id(m->id), args);
+ } else {
+ out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
+ "\t((%s_CLASS(parent_class)->%s)? \\\n"
+ "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
+ "\t\t(",
+ args, s, get_real_id(m->id), s, get_real_id(m->id), args);
+ out_printf(out, "(");
+ print_type(out, m->mtype, TRUE);
+ out_printf(out, ")%s))\n",
+ m->onerror?m->onerror:"0");
+ }
+ g_free(args);
+ g_free(s);
+ print_method_body(m, TRUE);
+ /* the outfile line was added above */
+ out_printf(out, "#undef PARENT_HANDLER\n");
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+open_files(void)
+{
+ char *outfile, *outfileh, *outfileph;
+
+ if(!for_cpp)
+ outfile = g_strconcat(filebase, ".c", NULL);
+ else
+ outfile = g_strconcat(filebase, ".cc", NULL);
+ if(no_touch_headers)
+ outfileh = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
+ else
+ outfileh = g_strconcat(filebase, ".h", NULL);
+
+ if((privates > 0 || protecteds > 0 ||
+ private_header == PRIVATE_HEADER_ALWAYS) &&
+ private_header != PRIVATE_HEADER_NEVER)
+ outfileph = g_strconcat(filebase, "-private.h", NULL);
+ else
+ outfileph = NULL;
+
+
+ if(no_write) {
+ devnull = fopen("/dev/null", "w");
+ if(!devnull)
+ g_error("Cannot open null device");
+ out = devnull;
+ outh = devnull;
+ if(outfileph)
+ outph = devnull;
+ } else {
+ out = fopen(outfile, "w");
+ if(!out) {
+ g_error("Cannot open outfile: %s", outfile);
+ }
+ outh = fopen(outfileh, "w");
+ if(!outh)
+ g_error("Cannot open outfile: %s", outfileh);
+ if(outfileph) {
+ outph = fopen(outfileph, "w");
+ if(!outph)
+ g_error("Cannot open outfile: %s", outfileh);
+ }
+ }
+}
+
+static void
+put_argument_nongnu_wrappers(Class *c)
+{
+ GList *li;
+
+ if(get_arguments < 0 && set_arguments < 0)
+ return;
+
+ for(li=c->nodes;li;li=g_list_next(li)) {
+ Node *n = li->data;
+ Argument *a = (Argument *)n;
+ char *aname;
+ char *cast;
+
+ if(n->type != ARGUMENT_NODE)
+ continue;
+
+ aname = g_strdup(a->name);
+ g_strup(aname);
+
+ if(a->atype)
+ cast = get_type(a->atype, TRUE);
+ else
+ cast = g_strdup(get_cast(a->gtktype, TRUE));
+
+ if(cast) {
+ if(a->set)
+ out_printf(outh, "#define %s_ARG_%s(arg) \t"
+ "\"%s\",(%s)(arg)\n",
+ macrobase, aname, a->name, cast);
+ if(a->get)
+ out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
+ "\"%s\",(%s*)(arg)\n",
+ macrobase, aname, a->name, cast);
+ } else {
+ if(a->set)
+ out_printf(outh, "#define %s_ARG_%s(arg) \t"
+ "\"%s\",(arg)\n",
+ macrobase, aname, a->name);
+ if(a->get)
+ out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
+ "\"%s\",(arg)\n",
+ macrobase, aname, a->name);
+ }
+ g_free(cast);
+ g_free(aname);
+ }
+}
+
+static void
+put_argument_gnu_wrappers(Class *c)
+{
+ GList *li;
+
+ if(get_arguments < 0 && set_arguments < 0)
+ return;
+
+ for(li=c->nodes;li;li=g_list_next(li)) {
+ Node *n = li->data;
+ Argument *a = (Argument *)n;
+ char *s;
+ char *cast;
+ if(n->type != ARGUMENT_NODE)
+ continue;
+ s = g_strdup(a->name);
+ g_strup(s);
+ if(a->atype)
+ cast = get_type(a->atype, TRUE);
+ else
+ cast = g_strdup(get_cast(a->gtktype, TRUE));
+ if(cast) {
+ if(a->set)
+ out_printf(outh, "#define %s_ARG_%s(arg) \t"
+ "\"%s\",({%sz = (arg); z;})\n",
+ macrobase, s, a->name, cast);
+ if(a->get)
+ out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
+ "\"%s\",({%s*z = (arg); z;})\n",
+ macrobase, s, a->name, cast);
+ } else {
+ if(a->set)
+ out_printf(outh, "#define %s_ARG_%s(arg) \t"
+ "\"%s\",(arg)\n",
+ macrobase, s, a->name);
+ if(a->get)
+ out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
+ "\"%s\",(arg)\n",
+ macrobase, s, a->name);
+ }
+ g_free(cast);
+ g_free(s);
+ }
+}
+
+static void
+print_ccode_block(CCode *cc)
+{
+ FILE *fp;
+ switch(cc->cctype) {
+ case HT_CCODE:
+ /* HT code is printed exactly like normal header
+ code but is printed before */
+ case H_CCODE:
+ fp = outh;
+ out_printf(fp, "\n");
+ break;
+ case AT_CCODE:
+ /* AT code is printed exactly like normal 'all'
+ code but is printed before */
+ case A_CCODE:
+ if(outph) {
+ out_printf(outph, "\n");
+ out_printf(outph, "%s\n", cc->cbuf);
+ out_addline_infile(outph, cc->line_no);
+ out_addline_outfile(outph);
+ }
+ out_printf(outh, "\n");
+ out_printf(outh, "%s\n", cc->cbuf);
+ fp = out;
+ out_printf(fp, "\n");
+ out_addline_infile(fp, cc->line_no);
+ break;
+ default:
+ case C_CCODE:
+ fp = out;
+ out_printf(fp, "\n");
+ out_addline_infile(fp, cc->line_no);
+ break;
+ case PH_CCODE:
+ if(outph)
+ fp = outph;
+ else
+ fp = out;
+ out_printf(fp, "\n");
+ out_addline_infile(fp, cc->line_no);
+ break;
+ }
+ out_printf(fp, "%s\n", cc->cbuf);
+ if(cc->cctype == C_CCODE ||
+ cc->cctype == A_CCODE ||
+ cc->cctype == AT_CCODE ||
+ cc->cctype == PH_CCODE)
+ out_addline_outfile(fp);
+}
+
+static void
+print_class_block(Class *c)
+{
+ GList *l;
+ char *s;
+ gboolean printed_private = FALSE;
+
+ if(any_special) {
+ out_printf(out, "/* utility types we may need */\n");
+ if(special_array[SPECIAL_2POINTER])
+ out_printf(out, "typedef struct { "
+ "gpointer a; gpointer b; "
+ "} ___twopointertype;\n");
+ if(special_array[SPECIAL_3POINTER])
+ out_printf(out, "typedef struct { "
+ "gpointer a; gpointer b; "
+ "gpointer c; "
+ "} ___threepointertype;\n");
+ if(special_array[SPECIAL_INT_POINTER])
+ out_printf(out, "typedef struct { "
+ "gint a; gpointer b; "
+ "} ___intpointertype;\n");
+ out_printf(out, "\n");
+ }
+
+ out_printf(outh, "\n/*\n"
+ " * Type checking and casting macros\n"
+ " */\n");
+ out_printf(outh, "#define %s\t"
+ "(%s_get_type())\n",
+ macrotype, funcbase);
+ out_printf(outh, "#define %s(obj)\t"
+ "GTK_CHECK_CAST((obj), %s_get_type(), %s)\n",
+ macrobase, funcbase, typebase);
+ out_printf(outh, "#define %s_CONST(obj)\t"
+ "GTK_CHECK_CAST((obj), %s_get_type(), %s const)\n",
+ macrobase, funcbase, typebase);
+ out_printf(outh, "#define %s_CLASS(klass)\t"
+ "GTK_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
+ macrobase, funcbase, typebase);
+ out_printf(outh, "#define %s(obj)\t"
+ "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
+ macrois, funcbase);
+ out_printf(outh, "#ifdef GTK_CHECK_GET_CLASS\n"
+ "#define %s_GET_CLASS(obj)\t"
+ "GTK_CHECK_GET_CLASS((obj), %s_get_type(), %sClass)\n",
+ macrobase, funcbase, typebase);
+ out_printf(outh, "#else /* !GTK_CHECK_GET_CLASS */\n"
+ "#define %s_GET_CLASS(obj)\t"
+ "((%sClass *)GTK_OBJECT(obj)->klass)\n"
+ "#endif /* GTK_CHECK_GET_CLASS */\n",
+ macrobase, typebase);
+
+ if( ! no_self_alias) {
+ out_printf(out, "/* self casting macros */\n");
+ out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
+ out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
+ out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
+ out_printf(out, "#define TYPE_SELF %s\n", macrotype);
+ out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
+ macrobase);
+ out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
+ macrobase);
+
+ out_printf(out, "/* self typedefs */\n");
+ out_printf(out, "typedef %s Self;\n", typebase);
+ out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
+ }
+
+ out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
+ out_printf(out,
+ "#ifndef GTK_CLASS_TYPE\n"
+ "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
+ "#endif /* GTK_CLASS_TYPE */\n\n");
+
+ if(privates > 0 || always_private_struct) {
+ out_printf(outh, "\n/* Private structure type */\n");
+ out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
+ typebase, typebase);
+ if(privates == 0)
+ out_printf(outh, "/* There are no privates, this "
+ "structure is thus never defined */\n");
+ }
+
+ out_printf(outh, "\n/*\n"
+ " * Main object structure\n"
+ " */\n");
+ s = replace_sep(c->otype, '_');
+ g_strup(s);
+ out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
+ "#define __TYPEDEF_%s__\n", s, s);
+ g_free(s);
+ out_printf(outh, "typedef struct _%s %s;\n"
+ "#endif\n", typebase, typebase);
+ out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
+ typebase, ptypebase);
+ for(l=c->nodes; l; l=g_list_next(l)) {
+ static gboolean printed_public = FALSE;
+ Node *n = l->data;
+ Variable *v = (Variable *)n;
+ if(n->type == VARIABLE_NODE &&
+ v->scope == PUBLIC_SCOPE) {
+ if( ! printed_public) {
+ out_printf(outh, "\t/*< public >*/\n");
+ printed_public = TRUE;
+ }
+ put_variable((Variable *)n, outh);
+ }
+ }
+ /* put protecteds always AFTER publics */
+ for(l=c->nodes; l; l=g_list_next(l)) {
+ Node *n = l->data;
+ Variable *v = (Variable *)n;
+ if(n->type == VARIABLE_NODE &&
+ v->scope == PROTECTED_SCOPE) {
+ if( ! printed_private) {
+ out_printf(outh, "\t/*< private >*/\n");
+ printed_private = TRUE;
+ }
+ put_variable((Variable *)n, outh);
+ }
+ }
+ if(privates > 0 || always_private_struct) {
+ if( ! printed_private)
+ out_printf(outh, "\t/*< private >*/\n");
+ out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
+ }
+ out_printf(outh, "};\n");
+
+ if(privates > 0) {
+ FILE *outfp;
+
+ /* if we are to stick this into the private
+ header, if not stick it directly into the
+ C file */
+ if(outph)
+ outfp = outph;
+ else
+ outfp = out;
+
+ out_printf(outfp, "struct _%sPrivate {\n",
+ typebase);
+ for(l=c->nodes; l; l=l->next) {
+ Node *n = l->data;
+ Variable *v = (Variable *)n;
+ if(n->type == VARIABLE_NODE &&
+ v->scope == PRIVATE_SCOPE) {
+ out_addline_infile(outfp, v->line_no);
+ put_variable(v, outfp);
+ }
+ }
+ out_addline_outfile(outfp);
+ out_printf(outfp, "};\n");
+ }
+
+ out_printf(outh, "\n/*\n"
+ " * Class definition\n"
+ " */\n");
+ out_printf(outh, "typedef struct _%sClass %sClass;\n",
+ typebase, typebase);
+ out_printf(outh,
+ "struct _%sClass {\n\t%sClass __parent__;\n",
+ typebase, ptypebase);
+ for(l = c->nodes; l != NULL; l = l->next) {
+ Node *n = l->data;
+ if(n->type == METHOD_NODE)
+ put_vs_method((Method *)n);
+ }
+ /* If BonoboX type class put down the epv */
+ if (c->bonobo_x_class != NULL) {
+ out_printf (outh,
+ "\t/* Bonobo object epv */\n"
+ "\tPOA_%s__epv _epv;\n",
+ c->bonobo_x_class);
+ }
+ /* put class scope variables */
+ for(l = c->nodes; l != NULL; l = l->next) {
+ Node *n = l->data;
+ Variable *v = (Variable *)n;
+ if(n->type == VARIABLE_NODE &&
+ v->scope == CLASS_SCOPE)
+ put_variable((Variable *)n, outh);
+ }
+ out_printf(outh, "};\n\n");
+
+ out_printf(out, "/* here are local prototypes */\n");
+ if(set_arguments > 0) {
+ out_printf(out, "static void ___object_set_arg "
+ "(GtkObject *object, GtkArg *arg, "
+ "guint arg_id);\n");
+ }
+ if(get_arguments > 0) {
+ out_printf(out, "static void ___object_get_arg "
+ "(GtkObject *object, GtkArg *arg, "
+ "guint arg_id);\n");
+ }
+
+ out_printf(outh, "\n/*\n"
+ " * Public methods\n"
+ " */\n");
+
+ if ( ! overrode_get_type) {
+ out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase);
+ if ( ! no_gnu) {
+ out_printf(outh, " G_GNUC_CONST;\n");
+ } else {
+ out_printf(outh, ";\n");
+ }
+ }
+
+ for(l = c->nodes; l != NULL; l = l->next) {
+ Node *n = l->data;
+ if(n->type == METHOD_NODE) {
+ put_pub_method((Method *)n);
+ put_prot_method((Method *)n);
+ put_priv_method_prot((Method *)n);
+ }
+ }
+
+ /* this idea is less and less apealing to me */
+ if (signals > 0) {
+ out_printf (outh, "\n/*\n"
+ " * Signal connection wrapper macros\n"
+ " */\n");
+ if( ! no_gnu) {
+ out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
+ put_signal_macros (c, TRUE);
+ out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
+ put_signal_macros (c, FALSE);
+ out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
+ } else {
+ put_signal_macros (c, FALSE);
+ }
+ }
+
+ /* argument wrapping macros */
+ if(get_arguments > 0 || set_arguments > 0) {
+ out_printf(outh, "\n/*\n"
+ " * Argument wrapping macros\n"
+ " */\n");
+ if( ! no_gnu) {
+ out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
+ put_argument_gnu_wrappers(c);
+ out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
+ put_argument_nongnu_wrappers(c);
+ out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
+ } else {
+ put_argument_nongnu_wrappers(c);
+ }
+ }
+
+ if(signals > 0) {
+ for(l = c->nodes; l != NULL; l = l->next) {
+ Node *n = l->data;
+ if(n->type == METHOD_NODE)
+ add_signal_prots((Method *)n);
+ }
+ }
+
+ add_enums(c);
+
+ if ( ! overrode_get_type) {
+ if (c->bonobo_x_class != NULL)
+ add_bonobo_x_get_type ();
+ else
+ add_get_type ();
+ }
+
+ if(any_method_to_alias(c)) {
+ if( ! no_gnu) {
+ out_printf(out, "/* Short form macros */\n");
+ out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
+ make_method_gnu_aliases(c);
+ out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");