X-Git-Url: http://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/2255b3d84eeb947d4c065332f16e410ae4704c63..774037b15064dcc6e4995c0bba3b24abb1bde35f:/src/main.c?ds=sidebyside diff --git a/src/main.c b/src/main.c index b429ef9..d58aef4 100644 --- a/src/main.c +++ b/src/main.c @@ -71,6 +71,7 @@ FILE *outph = NULL; gboolean no_touch_headers = FALSE; gboolean for_cpp = FALSE; +gboolean no_gnu = FALSE; gboolean exit_on_warn = FALSE; gboolean exit_on_error = TRUE; gboolean got_error = FALSE; @@ -189,17 +190,19 @@ make_bases(void) ptypebase = remove_sep(((Class *)class)->ptype); } -static void -print_type(FILE *fp, Type *t, gboolean postfix_to_stars) +static char * +get_type(Type *t, gboolean postfix_to_stars) { char *s; int i; int extra; + GString *gs; s = remove_sep(t->name); - out_printf(fp,"%s ",s); + gs = g_string_new(s); g_free(s); + extra = 0; if(postfix_to_stars) { char *p; @@ -210,11 +213,27 @@ print_type(FILE *fp, Type *t, gboolean postfix_to_stars) for(p=t->postfix; p && *p; p++) if(*p == '[') extra++; } + g_string_append_c(gs,' '); for(i=0;i<(t->stars+extra);i++) - out_printf(fp,"*"); + g_string_append_c(gs,'*'); + + s = gs->str; + g_string_free(gs,FALSE); + return s; } +static void +print_type(FILE *fp, Type *t, gboolean postfix_to_stars) +{ + char *s; + + s = get_type(t,postfix_to_stars); + out_printf(fp,"%s",s); + g_free(s); +} + + static void print_method(FILE *fp, char *typeprefix, char *nameprefix, char *namepostfix,char *postfix, Method *m, @@ -254,11 +273,39 @@ print_method(FILE *fp, char *typeprefix, char *nameprefix, static void -make_method_pointers(Class *c) +make_method_gnu_aliases(Class *c) +{ + GList *li; + + for(li=c->nodes;li;li=g_list_next(li)) { + Node *node = li->data; + if(node->type == METHOD_NODE) { + Method *m = (Method *)node; + + if(m->method == INIT_METHOD || + m->method == CLASS_INIT_METHOD || + m->method == OVERRIDE_METHOD) + continue; + + /* in C++ mode don't alias new */ + if(for_cpp && strcmp(m->id, "new")==0) + continue; + + out_printf(out, "static const typeof(&%s_%s) %s " + "__attribute__ ((__unused__)) " + "= %s_%s;\n", funcbase, m->id, m->id, + funcbase, m->id); + out_printf(out, "#define %s(args...) " + "%s_%s(##args)\n", m->id, funcbase, m->id); + } + } +} + +static void +make_method_nongnu_aliases(Class *c) { GList *li; - out_printf(out,"\n"); for(li=c->nodes;li;li=g_list_next(li)) { Node *node = li->data; if(node->type == METHOD_NODE) { @@ -279,7 +326,6 @@ make_method_pointers(Class *c) made_aliases = TRUE; } } - out_printf(out,"\n"); } static void @@ -291,12 +337,16 @@ add_bad_hack_to_avoid_unused_warnings(Class *c) if(!made_aliases) return; - out_printf(out,"\n\n/*REALLY BAD HACK\n" + if(!no_gnu) + out_printf(out,"\n\n#ifndef __GNUC__\n"); + out_printf(out, + "/*REALLY BAD HACK\n" " This is to avoid unused warnings if you don't call\n" " some method. I need to find a better way to do\n" - " this */\n"); - out_printf(out,"static void\n" - "__%s_really_bad_hack_to_avoid_warnings(void)\n" + " this, not needed in GCC since we use some gcc\n" + " extentions to make saner, faster code */\n" + "static void\n" + "___%s_really_bad_hack_to_avoid_warnings(void)\n" "{\n",funcbase); for(li=c->nodes;li;li=g_list_next(li)) { Node *node = li->data; @@ -315,9 +365,12 @@ add_bad_hack_to_avoid_unused_warnings(Class *c) out_printf(out,"\t((void (*)(void))%s)();\n",m->id); } } - out_printf(out, "\t__%s_really_bad_hack_to_avoid_warnings();\n", + out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n", funcbase); - out_printf(out,"}\n\n"); + if(!no_gnu) + out_printf(out,"}\n#endif /* __GNUC__ */\n\n"); + else + out_printf(out,"}\n\n"); } static void @@ -380,7 +433,9 @@ put_priv_method_prot(Method *m) m->method == CLASS_INIT_METHOD || (m->method == OVERRIDE_METHOD && m->cbuf)) - print_method(out,"static ",""," ",";\n",m,FALSE); + print_method(out,"static ",""," ", + no_gnu?";\n":" ___NO_UNUSED_WARNING;\n" + ,m,FALSE); } static GList * @@ -441,9 +496,9 @@ make_inits(Class *cl) } static void -make_destroy(Class *cl) +make_finalize(Class *cl) { - int got_destroy = FALSE; + int got_finalize = FALSE; GList *li; Node *node; for(li=cl->nodes;li;li=g_list_next(li)) { @@ -451,12 +506,12 @@ make_destroy(Class *cl) if(n->type == METHOD_NODE) { Method *m = (Method *)n; if(m->method == OVERRIDE_METHOD && - strcmp(m->id,"destroy")==0) { + strcmp(m->id,"finalize")==0) { if(strcmp(m->otype,"Gtk:Object")==0) { - got_destroy = TRUE; + got_finalize = TRUE; break; } else { - print_error(FALSE,"destroy method override " + print_error(FALSE,"finalize method override " "of class other then Gtk:Object", m->line_no); } @@ -464,11 +519,11 @@ make_destroy(Class *cl) } } } - if(!got_destroy) { + if(!got_finalize) { node = new_method(NO_SCOPE, OVERRIDE_METHOD, (Type *)new_type(0,g_strdup("void"),NULL), g_strdup("Gtk:Object"), - NULL,g_strdup("destroy"), + NULL,g_strdup("finalize"), make_func_arg("Gtk:Object",FALSE,g_strdup("o")), NULL, g_strdup("PARENT_HANDLER (o);\n"), @@ -482,40 +537,44 @@ make_destroy(Class *cl) /* the commented out types mean that these types don't actually exist. so we "emulate them" with an equivalent */ const struct { + gboolean simple; char *gtkname; char *typename; } our_gtk_type_table[] = { - { "NONE", "void" }, - { "CHAR", "gchar" }, - { "UCHAR", "guchar" }, - { "BOOL", "gboolean" }, - { "INT", "gint" }, - { "UINT", "guint" }, - { "LONG", "glong" }, - { "ULONG", "gulong" }, - { "FLOAT", "gfloat" }, - { "DOUBLE", "gdouble" }, - { "STRING", /*"GtkString"*/"gchar *" }, - { "ENUM", /*"GtkEnum"*/"gint" }, - { "FLAGS", /*"GtkFlags"*/"guint" }, - { "BOXED", /*"GtkBoxed"*/"gpointer" }, - { "POINTER", "gpointer" }, - { "OBJECT", "GtkObject *" }, - { "SIGNAL", /*"GtkSignal"*/"__twopointertype" }, - { "ARGS", /*"GtkArgs"*/"__twopointertype" }, - { "CALLBACK", /*"GtkCallback"*/"__threepointertype" }, - { "C_CALLBACK", /*"GtkCCallback"*/"__twopointertype" }, - { "FOREIGN", /*"GtkForeign"*/"__twopointertype" }, - - { NULL, NULL } + { TRUE, "NONE", "void " }, + { TRUE, "CHAR", "gchar " }, + { TRUE, "UCHAR", "guchar " }, + { TRUE, "BOOL", "gboolean " }, + { TRUE, "INT", "gint " }, + { TRUE, "UINT", "guint " }, + { TRUE, "LONG", "glong " }, + { TRUE, "ULONG", "gulong " }, + { TRUE, "FLOAT", "gfloat " }, + { TRUE, "DOUBLE", "gdouble " }, + { TRUE, "STRING", /*"GtkString"*/"gchar *" }, + { TRUE, "ENUM", /*"GtkEnum"*/"gint " }, + { TRUE, "FLAGS", /*"GtkFlags"*/"guint " }, + { TRUE, "BOXED", /*"GtkBoxed"*/"gpointer " }, + { TRUE, "POINTER", "gpointer " }, + { TRUE, "OBJECT", "GtkObject *" }, + { FALSE, "SIGNAL", /*"GtkSignal"*/"___twopointertype " }, + { FALSE, "ARGS", /*"GtkArgs"*/"___twopointertype " }, + { FALSE, "CALLBACK", /*"GtkCallback"*/"___threepointertype " }, + { FALSE, "C_CALLBACK", /*"GtkCCallback"*/"___twopointertype " }, + { FALSE, "FOREIGN", /*"GtkForeign"*/"___twopointertype " }, + + { FALSE, NULL, NULL } }; static const char * -get_cast(char *type) +get_cast(char *type, gboolean simple_only) { int i; for(i=0;our_gtk_type_table[i].gtkname;i++) { if(strcmp(our_gtk_type_table[i].gtkname,type)==0) { + if(simple_only && + !our_gtk_type_table[i].simple) + return NULL; return our_gtk_type_table[i].typename; } } @@ -572,7 +631,7 @@ print_signal_marsal_args(Method *m) else { out_printf(out, ",\n\t\t(%s)" "GTK_VALUE_%s(args[%d])", - get_cast(li->data), + get_cast(li->data,FALSE), (char *)li->data,i); } } @@ -608,21 +667,21 @@ add_signal_prots(Method *m) return; } - s = g_strdup_printf("__Sig%d",sig++); + s = g_strdup_printf("Sig%d",sig++); g_hash_table_insert(marsh,m,s); eq_signal_methods = g_list_prepend(eq_signal_methods,m); /* we know that we'll know all the gtktypes (so get_cast can't fail) */ out_printf(out,"\ntypedef %s (*%s) (%s *, ", - get_cast(m->gtktypes->data),s, typebase); + get_cast(m->gtktypes->data,FALSE),s, typebase); for(li=m->gtktypes->next;li;li=g_list_next(li)) - out_printf(out,"%s, ",get_cast(li->data)); + out_printf(out,"%s, ",get_cast(li->data,FALSE)); out_printf(out,"gpointer);\n"); out_printf(out,"\nstatic void\n" - "marshal_%s (GtkObject * object,\n" + "___marshal_%s (GtkObject * object,\n" "\tGtkSignalFunc func,\n" "\tgpointer func_data,\n" "\tGtkArg * args)\n" @@ -781,7 +840,7 @@ add_signals(Class *c) last = TRUE; if(g_hash_table_lookup(marsh,m)) - mar = g_strconcat("marshal_", + mar = g_strconcat("___marshal_", (char *)g_hash_table_lookup(marsh,m), NULL); else @@ -860,6 +919,13 @@ 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)) { @@ -880,8 +946,32 @@ make_arguments(Class *c) else flags = g_string_new("GTK_ARG_WRITABLE"); - for(l=a->flags;l;l=g_list_next(l)) - g_string_sprintfa(flags," | GTK_ARG_%s",(char *)l->data); + 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) { + print_error(TRUE,"READWRITE, READABLE and " + "WRITABLE argument flags are " + "set automatically",a->line_no); + 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]) { + char *s; + s = g_strdup_printf("Unknown flag '%s' used, " + "perhaps it was misspelled", + flag); + print_error(TRUE,s,a->line_no); + g_free(s); + } + g_string_sprintfa(flags, " | GTK_ARG_%s",flag); + } s = g_strdup(a->name); g_strup(s); @@ -895,8 +985,8 @@ make_arguments(Class *c) } out_printf(out, - "\n\tgtk_object_class->set_arg = __object_set_arg;\n" - "\tgtk_object_class->get_arg = __object_get_arg;\n"); + "\n\tgtk_object_class->set_arg = ___object_set_arg;\n" + "\tgtk_object_class->get_arg = ___object_get_arg;\n"); } static void @@ -977,7 +1067,7 @@ add_getset_arg(Class *c, int is_set) { GList *li; out_printf(out,"\nstatic void\n" - "__object_%s_arg (GtkObject *object,\n" + "___object_%s_arg (GtkObject *object,\n" "\tGtkArg *arg,\n" "\tguint arg_id)\n" "{\n" @@ -1025,12 +1115,16 @@ 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->stars == 0); 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 @@ -1038,10 +1132,16 @@ print_checks(Method *m, FuncArg *fa) 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"); - out_printf(out,"%s (%s)",s,fa->name); + 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: @@ -1084,6 +1184,8 @@ print_preconditions(Method *m) if(fa->checks) print_checks(m,fa); } + if(m->line_no>0) + out_addline_outfile(out); } /* put in code if it's needed */ @@ -1093,14 +1195,13 @@ put_in_gen_code(Method *m) /* now we only have the freeing of the private structure */ if(privates>0 && m->method == OVERRIDE_METHOD && - strcmp(m->id,"destroy")==0) { + strcmp(m->id,"finalize")==0) { out_printf(out,"\tg_free (%s (%s)->_priv);\n" "\t%s (%s)->_priv = NULL;\n", macrobase, ((FuncArg *)m->args->data)->name, macrobase, ((FuncArg *)m->args->data)->name); - } } @@ -1110,6 +1211,7 @@ print_method_body(Method *m, int pre) out_printf(out,"{\n"); if(pre) print_preconditions(m); + put_in_gen_code(m); /* Note: the trailing }'s are on one line, this is so @@ -1119,7 +1221,8 @@ print_method_body(Method *m, int pre) human readable anyway. */ if(m->cbuf) { out_printf(out,"{\n"); - out_addline_infile(out,m->ccode_line); + if(m->ccode_line>0) + out_addline_infile(out,m->ccode_line); out_printf(out,"\t%s}",m->cbuf); } @@ -1138,7 +1241,7 @@ put_signal_args(Method *m) li && ali; li=li->next, ali=ali->next) { FuncArg *fa = li->data; - const char *cast = get_cast(ali->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); @@ -1148,17 +1251,35 @@ put_signal_args(Method *m) } } +static char * +get_arg_names_for_macro(Method *m) +{ + char *p; + GList *li; + GString *gs = g_string_new(""); + 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; + char *s,*args; gboolean is_void; is_void = (strcmp(m->mtype->name,"void")==0 && m->mtype->stars == 0); out_printf(out,"\n"); switch(m->method) { case REGULAR_METHOD: - out_addline_infile(out,m->line_no); + 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); else /* PUBLIC, PROTECTED */ @@ -1167,7 +1288,8 @@ put_method(Method *m) break; case SIGNAL_FIRST_METHOD: case SIGNAL_LAST_METHOD: - out_addline_infile(out,m->line_no); + 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); else @@ -1200,12 +1322,14 @@ put_method(Method *m) if(!m->cbuf) break; - out_addline_infile(out,m->line_no); + if(m->line_no>0) + out_addline_infile(out,m->line_no); print_method(out,"static ","\n_real_"," ","\n",m,FALSE); print_method_body(m,FALSE); break; case VIRTUAL_METHOD: - out_addline_infile(out,m->line_no); + 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); else @@ -1245,33 +1369,37 @@ put_method(Method *m) if(!m->cbuf) break; - out_addline_infile(out,m->line_no); + if(m->line_no>0) + out_addline_infile(out,m->line_no); print_method(out,"static ","\n_real_"," ","\n",m,FALSE); print_method_body(m,FALSE); break; case OVERRIDE_METHOD: if(!m->cbuf) break; - out_addline_infile(out,m->line_no); + if(m->line_no>0) + out_addline_infile(out,m->line_no); print_method(out,"static ","\n"," ","\n",m,FALSE); s = replace_sep(m->otype,'_'); g_strup(s); + args = get_arg_names_for_macro(m); if(is_void) { - out_printf(out,"#define PARENT_HANDLER(args...) \\\n" + out_printf(out,"#define PARENT_HANDLER(%s) \\\n" "\t{ if(%s_CLASS(parent_class)->%s) \\\n" - "\t\t(* %s_CLASS(parent_class)->%s)(##args); }\n", - s,m->id,s,m->id); + "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n", + args,s,m->id,s,m->id,args); } else { - out_printf(out,"#define PARENT_HANDLER(args...) \\\n" + out_printf(out,"#define PARENT_HANDLER(%s) \\\n" "\t((%s_CLASS(parent_class)->%s)? \\\n" - "\t\t(* %s_CLASS(parent_class)->%s)(##args): \\\n" + "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n" "\t\t(", - s,m->id,s,m->id); + args,s,m->id,s,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); out_printf(out,"#undef PARENT_HANDLER\n"); @@ -1348,13 +1476,22 @@ check_bad_symbols(Class *c) print_error(FALSE,s,m->line_no); g_free(s); } + if(m->method != INIT_METHOD && + m->method != CLASS_INIT_METHOD && + (strcmp(m->id,"init")==0 || + strcmp(m->id,"class_init")==0)) { + print_error(FALSE,"init, or class_init not " + "allowed as an " + "identifier of non-" + "constructor methods",m->line_no); + } } else if(n->type == VARIABLE_NODE) { Variable *v = (Variable *)n; if(strcmp(v->id,"_priv")==0 || strcmp(v->id,"__parent__")==0) { - char *s; - s = g_strdup_printf("'%s' not allowed as a data " - "member name",v->id); + char *s; + s = g_strdup_printf("'%s' not allowed as a " + "data member name",v->id); print_error(FALSE,s,v->line_no); g_free(s); } @@ -1525,7 +1662,7 @@ check_signal_args(Class *c) for(l=m->gtktypes;l;l=l->next) { char *s; - if(get_cast(l->data)) + if(get_cast(l->data,FALSE)) continue; s = g_strdup_printf("Unknown GTK+ type '%s' " "among signal types", @@ -1537,6 +1674,29 @@ check_signal_args(Class *c) } } +static void +check_argument_types(Class *c) +{ + GList *l; + for(l=c->nodes;l;l=g_list_next(l)) { + Node *n = l->data; + if(n->type == ARGUMENT_NODE) { + Argument *a = (Argument *)n; + char *s; + if(get_cast(a->gtktype,FALSE)) + continue; + s = g_strdup_printf("Unknown GTK+ type '%s' " + "as argument type", + a->gtktype); + /* this could perhaps be a warning, but + can there really be a type beyond the + fundementals? */ + print_error(FALSE, s, a->line_no); + g_free(s); + } + } +} + static int count_signals(Class *c) { @@ -1654,6 +1814,97 @@ open_files(void) } } +static void +put_argument_nongnu_wrappers(Class *c) +{ + GList *li; + + if(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\",(%s)(arg)\n", + macrobase, s, a->name, cast); + if(a->get) + out_printf(outh, "#define %s_GET_ARG_%s(arg)\t" + "\"%s\",(%s*)(arg)\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 +put_argument_gnu_wrappers(Class *c) +{ + GList *li; + + if(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 generate_outfiles(void) { @@ -1670,6 +1921,15 @@ generate_outfiles(void) " (do not edit directly) */\n\n",VERSION); out_printf(out,"/* Generated by GOB (v%s) on %s" " (do not edit directly) */\n\n",VERSION,ctime(&curtime)); + + { + int major=0,minor=0,pl=0; + sscanf(VERSION,"%d.%d.%d",&major,&minor,&pl); + + out_printf(out,"#define GOB_VERSION_MAJOR %d\n", major); + out_printf(out,"#define GOB_VERSION_MINOR %d\n", minor); + out_printf(out,"#define GOB_VERSION_PATCHLEVEL %d\n\n", pl); + } p = replace_sep(((Class *)class)->otype,'_'); g_strup(p); @@ -1742,11 +2002,11 @@ generate_outfiles(void) out_printf(out,"/* utility types we may need */\n"); out_printf(out,"typedef struct { " "gpointer a; gpointer b; " - "} __twopointertype;\n"); + "} ___twopointertype;\n"); out_printf(out,"typedef struct { " "gpointer a; gpointer b; " "gpointer c; " - "} __threepointertype;\n"); + "} ___threepointertype;\n"); out_printf(outh,"\n#define %s\t" "(%s_get_type())\n", @@ -1761,6 +2021,17 @@ generate_outfiles(void) "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n", macrois,funcbase); + /* argument wrapping macros */ + if(arguments>0 && !no_gnu) { + out_printf(outh,"\n#ifdef __GNUC__\n"); + put_argument_gnu_wrappers(c); + out_printf(outh,"#else /* __GNUC__ */\n"); + put_argument_nongnu_wrappers(c); + out_printf(outh,"#endif /* __GNUC__ */\n\n"); + } else if(arguments>0 && no_gnu) { + put_argument_nongnu_wrappers(c); + } + if(privates>0) out_printf(outh,"\ntypedef struct _%sPrivate %sPrivate;\n",typebase,typebase); @@ -1826,16 +2097,24 @@ generate_outfiles(void) out_printf(outh,"guint\t%s_get_type\t(void);\n",funcbase); + out_printf(out,"/* here are local prototypes */\n"); + if(!no_gnu) { + out_printf(out,"#ifdef __GNUC__\n" + "#define ___NO_UNUSED_WARNING " + "__attribute__ ((__unused__))\n" + "#else /* __GNUC__ */\n" + "#define ___NO_UNUSED_WARNING\n" + "#endif /* __GNUC__ */\n"); + } if(arguments>0) { - out_printf(out,"static void __object_set_arg " + out_printf(out,"static void ___object_set_arg " "(GtkObject *object, GtkArg *arg, " "guint arg_id);\n" - "static void __object_get_arg " + "static void ___object_get_arg " "(GtkObject *object, GtkArg *arg, " "guint arg_id);\n"); } - out_printf(out,"/* here are local prototypes */\n"); for(l=c->nodes;l;l=g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { @@ -1852,12 +2131,23 @@ generate_outfiles(void) add_signal_prots((Method *)n); } } + + if(!no_gnu) + out_printf(out,"#undef ___NO_UNUSED_WARNING\n"); add_enums(c); add_get_type(); - make_method_pointers(c); + if(no_gnu) + make_method_nongnu_aliases(c); + else { + out_printf(out,"\n#ifdef __GNUC__\n"); + make_method_gnu_aliases(c); + out_printf(out,"#else /* __GNUC__ */\n"); + make_method_nongnu_aliases(c); + out_printf(out,"#endif /* __GNUC__ */\n\n"); + } out_printf(out,"#define GET_NEW (gtk_type_new(%s_get_type()))\n", funcbase); @@ -1917,6 +2207,7 @@ print_help(void) "\t--exit-on-warn,-w Exit with an error on warnings\n" "\t--no-exit-on-warn Don't exit on warnings [default]\n" "\t--for-cpp Create C++ files\n" + "\t--no-gnu Never use GNU extentions\n" "\t--no-touch-headers Don't touch headers unless they " "really changed\n" "\t--always-private-header Always create a private header " @@ -1967,6 +2258,8 @@ parse_options(int argc, char *argv[]) } else if(strcmp(argv[i],"--no-private-header")==0) { always_private_header = FALSE; no_private_header = TRUE; + } else if(strcmp(argv[i],"--no-gnu")==0) { + no_gnu = TRUE; } else if(strcmp(argv[i],"--")==0) { /*further arguments are files*/ no_opts = TRUE; @@ -2091,7 +2384,7 @@ main(int argc, char *argv[]) make_bases(); make_inits((Class *)class); if(privates>0) - make_destroy((Class *)class); + make_finalize((Class *)class); check_bad_symbols((Class *)class); check_duplicate_symbols((Class *)class); check_duplicate_signals_args((Class *)class); @@ -2100,6 +2393,7 @@ main(int argc, char *argv[]) check_firstarg((Class *)class); check_nonvoidempty((Class *)class); check_signal_args((Class *)class); + check_argument_types((Class *)class); exit_on_error = TRUE;