+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)