X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/96e3b08533ea7fc6bd4b4de58849da0dec72411c..refs/tags/v2.0.9:/src/main.c?ds=sidebyside diff --git a/src/main.c b/src/main.c index d22a7da..dfd87d0 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,9 @@ /* GOB C Preprocessor * Copyright (C) 1999,2000 the Free Software Foundation. * Copyright (C) 2000 Eazel, Inc. - * Copyright (C) 2001 George Lebl + * Copyright (C) 2001-2004 George (Jiri) Lebl * - * Author: George Lebl + * Author: George (Jiri) Lebl * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -53,6 +53,7 @@ extern GList *include_files; extern GHashTable *gtk_doc_hash; char *filebase; +char *fullfilebase; static char *funcbase; static char *pfuncbase; static char *macrobase; @@ -63,6 +64,8 @@ static char *pmacrotype; static char *typebase; static char *ptypebase; +char *output_dir = NULL; + static int signals = 0; /* number of signals */ static int set_properties = 0; /* number of named (set) properties */ static int get_properties = 0; /* number of named (get) properties */ @@ -120,16 +123,23 @@ static void make_bases (void) { filebase = replace_sep (((Class *)class)->otype, '-'); - g_strdown (filebase); + gob_strdown (filebase); + + if (output_dir != NULL && + output_dir[0] != '\0') { + fullfilebase = g_build_filename (output_dir, filebase, NULL); + } else { + fullfilebase = g_strdup (filebase); + } funcbase = replace_sep (((Class *)class)->otype, '_'); - g_strdown (funcbase); + gob_strdown (funcbase); pfuncbase = replace_sep (((Class *)class)->ptype, '_'); - g_strdown (pfuncbase); + gob_strdown (pfuncbase); macrobase = replace_sep (((Class *)class)->otype, '_'); - g_strup (macrobase); + gob_strup (macrobase); macrois = make_pre_macro (((Class *)class)->otype, "IS"); pmacrois = make_pre_macro (((Class *)class)->ptype, "IS"); @@ -183,7 +193,9 @@ print_method (FILE *fp, const Method *m, gboolean one_arg_per_line, gboolean no_funcbase, - gboolean kill_underscore) + gboolean kill_underscore, + gboolean first_unused, + gboolean fake_names) { GList *li; const char *id; @@ -204,16 +216,29 @@ print_method (FILE *fp, if(m->args) { for(li=m->args; li; li=g_list_next(li)) { FuncArg *arg = li->data; + const char *unused = ""; + + if ( ! no_gnu && + ! for_cpp && /* g++ has a cow with this */ + li == m->args && + first_unused) { + unused = " G_GNUC_UNUSED"; + } + print_type(fp, arg->atype, FALSE); + if (fake_names) + out_printf (fp, "___fake___"); if(li->next) - out_printf(fp, "%s%s,%s", arg->name, + out_printf(fp, "%s%s%s,%s", arg->name, arg->atype->postfix ? arg->atype->postfix : "", + unused, one_arg_per_line ? "\n\t\t\t\t\t" : " "); else - out_printf(fp, "%s%s", arg->name, + out_printf(fp, "%s%s%s", arg->name, arg->atype->postfix ? - arg->atype->postfix : ""); + arg->atype->postfix : "", + unused); } if(m->vararg) out_printf(fp, ",%s...", @@ -246,9 +271,8 @@ any_method_to_alias(Class *c) } -/* just the vararg macros, we use the same func pointers for these as in non-gnu */ static void -make_method_gnu_aliases(Class *c) +make_method_aliases (Class *c) { GList *li; @@ -262,51 +286,12 @@ make_method_gnu_aliases(Class *c) m->method == OVERRIDE_METHOD) continue; - if(m->args != NULL) - out_printf(out, "#define self_%s(args...) " - "%s_%s(args)\n", m->id, - funcbase, m->id); - else - out_printf(out, "#define self_%s() " - "%s_%s()\n", m->id, - funcbase, m->id); - } - } -} - -static void -make_method_nongnu_aliases(Class *c) -{ - GList *li; - - gboolean local_made_aliases = FALSE; - - 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; - - if( ! local_made_aliases) - out_printf(out, "\n/* Short form pointers */\n"); - - print_method(out, "static ", "(* const self_", "", ") ", - "", "", - m, FALSE, TRUE, FALSE); - out_printf(out, " = %s_%s;\n", funcbase, - m->id); - - local_made_aliases = TRUE; + out_printf (out, "#define self_%s %s_%s\n", + m->id, + funcbase, + m->id); } } - if(local_made_aliases) { - out_printf(out, "\n"); - made_aliases = TRUE; - } } static void @@ -379,10 +364,10 @@ put_vs_method(const Method *m) /* if a signal mark it as such */ if(m->method != VIRTUAL_METHOD) print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n", - m, FALSE, TRUE, TRUE); + m, FALSE, TRUE, TRUE, FALSE, FALSE); else print_method(outh, "\t", "(* ", "", ") ", "", ";\n", - m, FALSE, TRUE, TRUE); + m, FALSE, TRUE, TRUE, FALSE, FALSE); } static void @@ -391,7 +376,8 @@ put_pub_method(const Method *m) if(m->scope != PUBLIC_SCOPE) return; - print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE); + print_method(outh, "", "\t", "", "\t", "", ";\n", m, + TRUE, FALSE, TRUE, FALSE, FALSE); } static void @@ -424,35 +410,35 @@ put_signal_macro (const Method *m, gboolean gnu) /* connect */ out_printf (outh, "#define %s_connect__%s(object,func,data)\t" "g_signal_connect(" - "%s(({%s *___object = (object); ___object; }))," + "%s(__extension__ ({%s *___object = (object); ___object; }))," "\"%s\"," - "(GCallback)({", + "(GCallback) __extension__ ({", funcbase, m->id, macrobase, typebase, m->id); print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ", - " = (func); ", m, FALSE, TRUE, TRUE); + " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE); out_printf (outh, "___%s; }), (data))\n", m->id); /* connect_after */ out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t" "g_signal_connect_after(" - "%s(({%s *___object = (object); ___object; }))," + "%s(__extension__ ({%s *___object = (object); ___object; }))," "\"%s\"," - "(GCallback)({", + "(GCallback) __extension__ ({", funcbase, m->id, macrobase, typebase, m->id); print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ", - " = (func); ", m, FALSE, TRUE, TRUE); + " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE); out_printf (outh, "___%s; }), (data))\n", m->id); /* connect_data */ out_printf (outh, "#define %s_connect_data__%s" "(object,func,data,destroy_data,flags)\t" "g_signal_connect_data(" - "%s(({%s *___object = (object); ___object; }))," + "%s(__extension__ ({%s *___object = (object); ___object; }))," "\"%s\"," - "(GCallback)({", + "(GCallback) __extension__ ({", funcbase, m->id, macrobase, typebase, m->id); print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ", - " = (func); ", m, FALSE, TRUE, TRUE); + " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE); out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id); } } @@ -519,10 +505,10 @@ put_prot_method(const Method *m) if(outph) print_method(outph, "", "\t", "", "\t", "", ";\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); else print_method(out, "", "\t", "", "\t", "", ";\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); } static void @@ -534,7 +520,7 @@ put_priv_method_prot(const Method *m) if(m->cbuf) print_method(out, "static ", "___real_", "", " ", "", ";\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); } /* no else, here, it might still have a private prototype, it's not * exclusive */ @@ -545,14 +531,14 @@ put_priv_method_prot(const Method *m) char *s = g_strdup_printf("___%x_", (guint)m->unique_id); print_method(out, "static ", s, "", " ", "", no_gnu?";\n":" G_GNUC_UNUSED;\n", - m, FALSE, FALSE, FALSE); + m, FALSE, FALSE, FALSE, FALSE, FALSE); g_free(s); } else if(m->scope == PRIVATE_SCOPE || m->method == INIT_METHOD || m->method == CLASS_INIT_METHOD) { print_method(out, "static ", "", "", " ", "", no_gnu?";\n":" G_GNUC_UNUSED;\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); } } @@ -751,7 +737,7 @@ print_signal_marsal_args (const Method *m) get_func = g_strdup_printf ("g_value_get_%s", (char *)li->data); - g_strdown (get_func); + gob_strdown (get_func); out_printf (out, ",\n\t\t(%s) " "%s (param_values + %d)", get_cast (li->data, FALSE), @@ -773,6 +759,11 @@ add_signal_prots(Method *m) gboolean ret_none = FALSE; gboolean arglist_none = FALSE; const char *retcast; + const char *unused = ""; + + if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) { + unused = " G_GNUC_UNUSED"; + } if (m->method != SIGNAL_LAST_METHOD && m->method != SIGNAL_FIRST_METHOD) @@ -819,12 +810,15 @@ add_signal_prots(Method *m) out_printf (out, "\nstatic void\n" "___marshal_%s (GClosure *closure,\n" - "\tGValue *return_value,\n" + "\tGValue *return_value%s,\n" "\tguint n_param_values,\n" "\tconst GValue *param_values,\n" - "\tgpointer invocation_hint,\n" + "\tgpointer invocation_hint%s,\n" "\tgpointer marshal_data)\n" - "{\n", s); + "{\n", + s, + unused, + unused); if ( ! ret_none) out_printf (out, "\t%s v_return;\n", retcast); @@ -875,13 +869,19 @@ add_signal_prots(Method *m) (char *)m->gtktypes->data, take_ownership ? "_take_ownership" : ""); - g_strdown (set_func); + gob_strdown (set_func); out_printf (out, "\n\t%s (return_value, v_return);\n", set_func); g_free (set_func); } + if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) { + if (ret_none) + out_printf (out, "\n\treturn_value = NULL;\n"); + out_printf (out, "\tinvocation_hint = NULL;\n"); + + } out_printf (out, "}\n\n"); } @@ -899,7 +899,7 @@ add_enums(Class *c) if(m->method == SIGNAL_LAST_METHOD || m->method == SIGNAL_FIRST_METHOD) { char *s = g_strdup(m->id); - g_strup(s); + gob_strup(s); out_printf(out, "\t%s_SIGNAL,\n", s); g_free(s); } @@ -915,13 +915,13 @@ add_enums(Class *c) if (n->type == PROPERTY_NODE) { Property *p = (Property *)n; char *s = g_strdup (p->name); - g_strup (s); + gob_strup (s); out_printf (out, ",\n\tPROP_%s", s); g_free(s); } else if (n->type == ARGUMENT_NODE) { Argument *a = (Argument *)n; char *s = g_strdup(a->name); - g_strup(s); + gob_strup (s); out_printf(out, ",\n\tPROP_%s", s); g_free(s); } @@ -1053,13 +1053,13 @@ static void add_get_type(void) { /*char *chunk_size = ((Class*)class)->chunk_size;*/ - + out_printf(out, "GType\n" "%s_get_type (void)\n" "{\n" "\tstatic GType type = 0;\n\n" - "\tif (type == 0) {\n" + "\tif ___GOB_UNLIKELY(type == 0) {\n" "\t\tstatic const GTypeInfo info = {\n" "\t\t\tsizeof (%sClass),\n" "\t\t\t(GBaseInitFunc) NULL,\n" @@ -1070,6 +1070,7 @@ add_get_type(void) "\t\t\tsizeof (%s),\n" "\t\t\t0 /* n_preallocs */,\n" "\t\t\t(GInstanceInitFunc) %s_init,\n" + "\t\t\tNULL\n" "\t\t};\n\n", funcbase, typebase, funcbase, typebase, funcbase); @@ -1112,7 +1113,7 @@ add_bonobo_object_get_type (void) "%s_get_type (void)\n" /* 1 */ "{\n" "\tstatic GType type = 0;\n\n" - "\tif (type == 0) {\n" + "\tif ___GOB_UNLIKELY(type == 0) {\n" "\t\tstatic const GTypeInfo info = {\n" "\t\t\tsizeof (%sClass),\n" /* 2 */ "\t\t\t(GBaseInitFunc) NULL,\n" @@ -1188,7 +1189,7 @@ add_overrides(Class *c, const char *oname, g_hash_table_insert(done, s, s); f = replace_sep(m->otype, '_'); - g_strdown(f); + gob_strdown(f); out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n", s, f, s, oname); @@ -1282,7 +1283,7 @@ add_signals(Class *c) is_none = (strcmp(m->gtktypes->next->data, "NONE")==0); sig = g_strdup (m->id); - g_strup (sig); + gob_strup (sig); flags = make_run_signal_flags (m, last); out_printf (out, "\tobject_signals[%s_SIGNAL] =\n" "\t\tg_signal_new (\"%s\",\n" @@ -1313,18 +1314,15 @@ add_signals(Class *c) if(strcmp(m->gtktypes->data, "NONE") != 0 || ! is_none) { GList *gl, *al; - const char *sep = ""; - out_printf(out, "\tif("); + out_printf(out, "\tif ___GOB_UNLIKELY("); if(strcmp(m->gtktypes->data, "NONE") != 0) { - out_printf(out, "%s sizeof(", sep); + out_printf(out, "sizeof("); print_type(out, m->mtype, FALSE); out_printf(out, "%s", m->mtype->postfix ? m->mtype->postfix : ""); - out_printf(out, ") != sizeof(%s)", + out_printf(out, ") != sizeof(%s) || ", get_cast(m->gtktypes->data, FALSE)); - - sep = " || "; } for(al = m->args->next, gl = m->gtktypes->next; @@ -1333,16 +1331,18 @@ add_signals(Class *c) FuncArg *arg = al->data; char *gtkarg = gl->data; - out_printf(out, "%ssizeof(", sep); + out_printf(out, "sizeof("); print_type(out, arg->atype, FALSE); out_printf(out, "%s", arg->atype->postfix ? arg->atype->postfix : ""); - out_printf(out, ") != sizeof(%s)", + out_printf(out, ") != sizeof(%s) || ", get_cast(gtkarg, FALSE)); - - sep = " || "; } + + out_printf (out, + "parent_class == NULL /* avoid warning */"); + out_printf(out, ") {\n" "\t\tg_error(\"%s line %d: Type mismatch " "of \\\"%s\\\" signal signature\");\n" @@ -1383,7 +1383,7 @@ set_def_handlers(Class *c, const char *oname) if (m->method == OVERRIDE_METHOD) { char *s; s = replace_sep (m->otype, '_'); - g_strdown (s); + gob_strdown (s); if (need_dispose && dispose_handler != NULL && @@ -1469,7 +1469,7 @@ make_argument (Argument *a) g_string_append (flags, ")"); s = g_strdup(a->name); - g_strup(s); + gob_strup (s); if (!strcmp (a->gtktype, "ENUM")) out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n" "\t\tG_TYPE_ENUM, 0,\n" @@ -1538,6 +1538,18 @@ make_argument (Argument *a) "\t\t0,\n" "\t\t%s);\n", a->name, flags->str); + else if (!strcmp (a->gtktype, "INT64")) + out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n" + "\t\tG_MININT64, G_MAXINT64,\n" + "\t\t0,\n" + "\t\t%s);\n", + a->name, flags->str); + else if (!strcmp (a->gtktype, "UINT64")) + out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n" + "\t\t0, G_MAXUINT64,\n" + "\t\t0,\n" + "\t\t%s);\n", + a->name, flags->str); else if (!strcmp (a->gtktype, "FLOAT")) out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n" "\t\tG_MINFLOAT, G_MAXFLOAT,\n" @@ -1569,21 +1581,6 @@ make_argument (Argument *a) #define value_for_print(str, alt) (str != NULL ? str : alt) -static char * -make_me_type (const char *type, const char *alt) -{ - if (type == NULL) - return g_strdup (alt); - /* HACK! just in case someone made this - * work with 2.0.0 by using the TYPE - * macro directly */ - if ((strstr (type, "_TYPE_") != NULL || - strstr (type, "TYPE_") == type) && - strchr (type, ':') == NULL) - return g_strdup (type); - return make_pre_macro (type, "TYPE"); -} - static void make_property (Property *p) { @@ -1746,6 +1743,38 @@ make_property (Property *p) value_for_print (p->maximum, "G_MAXULONG"), value_for_print (p->default_value, "0"), flags->str); + } else if (strcmp (p->gtktype, "INT64") == 0) { + out_printf (out, "\tparam_spec = g_param_spec_int64\n" + "\t\t(\"%s\" /* name */,\n" + "\t\t %s /* nick */,\n" + "\t\t %s /* blurb */,\n" + "\t\t %s /* minimum */,\n" + "\t\t %s /* maximum */,\n" + "\t\t %s /* default_value */,\n" + "\t\t %s);\n", + p->name, + value_for_print (p->nick, "NULL"), + value_for_print (p->blurb, "NULL"), + value_for_print (p->minimum, "G_MININT64"), + value_for_print (p->maximum, "G_MAXINT64"), + value_for_print (p->default_value, "0"), + flags->str); + } else if (strcmp (p->gtktype, "UINT64") == 0) { + out_printf (out, "\tparam_spec = g_param_spec_uint64\n" + "\t\t(\"%s\" /* name */,\n" + "\t\t %s /* nick */,\n" + "\t\t %s /* blurb */,\n" + "\t\t %s /* minimum */,\n" + "\t\t %s /* maximum */,\n" + "\t\t %s /* default_value */,\n" + "\t\t %s);\n", + p->name, + value_for_print (p->nick, "NULL"), + value_for_print (p->blurb, "NULL"), + value_for_print (p->minimum, "0"), + value_for_print (p->maximum, "G_MAXUINT64"), + value_for_print (p->default_value, "0"), + flags->str); } else if (strcmp (p->gtktype, "UNICHAR") == 0) { out_printf (out, "\tparam_spec = g_param_spec_unichar\n" "\t\t(\"%s\" /* name */,\n" @@ -1909,7 +1938,7 @@ make_property (Property *p) } s = g_strdup (p->name); - g_strup (s); + gob_strup (s); out_printf (out, "\tg_object_class_install_property (g_object_class,\n" "\t\tPROP_%s,\n" "\t\tparam_spec);\n", s); @@ -2019,8 +2048,10 @@ add_dispose (Class *c) c->otype); if (unreftors > 0) { - out_printf (out, "\t%s *self = %s (obj_self);\n", - typebase, macrobase); + out_printf (out, "\t%s *self%s = %s (obj_self);\n", + typebase, + ! no_gnu ? " G_GNUC_UNUSED" : "", + macrobase); } if (dispose_handler != NULL) { @@ -2051,9 +2082,6 @@ add_dispose (Class *c) } } - out_printf (out, "\treturn;\n"); - if (unreftors > 0) - out_printf(out, "\tself = NULL;\n"); out_printf(out, "}\n" "#undef __GOB_FUNCTION__\n\n"); } @@ -2071,8 +2099,11 @@ add_finalize (Class *c) if (privates > 0 || destructors > 0) { - out_printf(out, "\t%s *self = %s (obj_self);\n", - typebase, macrobase); + 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) { out_printf(out, "\tgpointer priv = self->_priv;\n"); @@ -2109,10 +2140,6 @@ add_finalize (Class *c) if (privates > 0) { out_printf(out, "\tg_free (priv);\n"); } - out_printf (out, "\treturn;\n"); - if (destructors > 0 || - privates > 0) - out_printf (out, "\tself = NULL;\n"); out_printf(out, "}\n" "#undef __GOB_FUNCTION__\n\n"); @@ -2151,13 +2178,16 @@ make_bonobo_object_epv (Class *c, const char *classname) 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; - gboolean add_unused_class = FALSE; - if(n->type != METHOD_NODE) continue; m = (Method *)n; @@ -2165,7 +2195,7 @@ add_inits(Class *c) if(m->line_no > 0) out_addline_infile(out, m->line_no); print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, TRUE, FALSE); if(m->line_no > 0) out_addline_outfile(out); out_printf(out, "{\n" @@ -2199,7 +2229,7 @@ add_inits(Class *c) if(m->line_no > 0) out_addline_infile(out, m->line_no); print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, TRUE, FALSE); if(m->line_no > 0) out_addline_outfile(out); out_printf(out, "{\n" @@ -2212,10 +2242,10 @@ add_inits(Class *c) need_finalize) { out_printf(out, "\tGObjectClass *" - "g_object_class = " + "g_object_class%s = " "(GObjectClass*) %s;\n", + unused, ((FuncArg *)m->args->data)->name); - add_unused_class = TRUE; did_base_obj = TRUE; } @@ -2273,13 +2303,6 @@ add_inits(Class *c) 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, "\tg_object_class = NULL;\n"); - } out_printf(out, "}\n" "#undef __GOB_FUNCTION__\n"); } @@ -2303,11 +2326,11 @@ add_argument (Argument *a, gboolean is_set) if (cbuf == NULL) return; s = g_strdup(a->name); - g_strup(s); + gob_strup (s); out_printf(out, "\tcase PROP_%s:\n\t{", s); the_type_lower = g_strdup (a->gtktype); - g_strdown (the_type_lower); + gob_strdown (the_type_lower); /* HACK because there is no g_value_set/get for unichar */ if (strcmp (the_type_lower, "unichar") == 0) { @@ -2317,14 +2340,25 @@ add_argument (Argument *a, gboolean is_set) if (is_set) { char *cast; + const char *unused = ""; - if (a->atype != NULL) + 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) g_value_get_%s (VAL);\n", - cast, cast, the_type_lower); + 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) { @@ -2359,8 +2393,9 @@ add_argument (Argument *a, gboolean is_set) } g_free (the_type_lower); - if (is_set) { - out_printf (out, "\t\tif (&ARG) ;\n"); + 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"); @@ -2387,9 +2422,9 @@ add_property (Property *p, gboolean is_set) return; name_upper = g_strdup (p->name); - g_strup (name_upper); + gob_strup (name_upper); the_type_lower = g_strdup (p->gtktype); - g_strdown (the_type_lower); + gob_strdown (the_type_lower); out_printf (out, "\tcase PROP_%s:\n", name_upper); @@ -2411,20 +2446,34 @@ 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,\n" - "\tGParamSpec *pspec)\n" + "\t%sGValue *VAL%s,\n" + "\tGParamSpec *pspec%s)\n" "#define __GOB_FUNCTION__ \"%s::%s_property\"\n" "{\n" - "\t%s *self;\n\n" + "\t%s *self%s;\n\n" "\tself = %s (object);\n\n" "\tswitch (property_id) {\n", is_set ? "set" : "get", is_set ? "const " : "", - c->otype, is_set ? "set" : "get", - typebase, macrobase); + unused, + unused, + c->otype, + is_set ? "set" : "get", + typebase, + unused, + macrobase); for (li = c->nodes; li != NULL; li = li->next) { Node *n = li->data; @@ -2440,9 +2489,9 @@ add_getset_arg(Class *c, gboolean is_set) "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n" "#endif\n" "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n" - "\t\tbreak;\n\t}\n" - "\treturn;\n\tself = NULL;\n\tVAL = NULL;\n\tpspec = NULL;\n}\n" - "#undef __GOB_FUNCTION__\n"); + "\t\t%sbreak;\n\t}\n" + "}\n" + "#undef __GOB_FUNCTION__\n", hack_unused); } static void @@ -2524,7 +2573,7 @@ print_preconditions(Method *m) } static void -print_method_body(Method *m, int pre) +print_method_body (Method *m, gboolean pre, gboolean unused_self) { if (m->line_no > 0) out_addline_outfile(out); @@ -2532,9 +2581,18 @@ print_method_body(Method *m, int pre) "#define __GOB_FUNCTION__ \"%s::%s\"\n", ((Class *)class)->otype, m->id); - if(pre) + 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 @@ -2597,7 +2655,7 @@ put_signal_args (Method *m) set_func = g_strdup_printf ("g_value_set%s_%s", do_static ? "_static" : "", (char *)ali->data); - g_strdown (set_func); + gob_strdown (set_func); out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n", set_func, i, cast, fa->name); @@ -2607,6 +2665,25 @@ put_signal_args (Method *m) } } +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) { @@ -2643,11 +2720,11 @@ put_method(Method *m) out_addline_infile(out, m->line_no); if(m->scope == PRIVATE_SCOPE) print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); else /* PUBLIC, PROTECTED */ print_method(out, "", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); - print_method_body(m, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method_body(m, TRUE, TRUE); /* the outfile line was added above */ break; case SIGNAL_FIRST_METHOD: @@ -2656,17 +2733,21 @@ put_method(Method *m) out_addline_infile(out, m->line_no); if(m->scope == PRIVATE_SCOPE) print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); else /* PUBLIC, PROTECTED */ print_method(out, "", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); out_addline_outfile (out); out_printf (out, "{\n"); out_printf (out, "\tGValue ___param_values[%d];\n" - "\tGValue ___return_val = {0};\n\n", + "\tGValue ___return_val;\n\n" + "memset (&___return_val, 0, " + "sizeof (___return_val));\n" + "memset (&___param_values, 0, " + "sizeof (___param_values));\n\n", g_list_length (m->args)); print_preconditions (m); @@ -2708,7 +2789,7 @@ put_method(Method *m) set_func = g_strdup_printf ("g_value_set%s_%s", do_static ? "_static" : "", (char *)m->gtktypes->data); - g_strdown (set_func); + gob_strdown (set_func); out_printf (out, "\t%s (&___return_val, (%s) (%s));\n", set_func, cast, defret); @@ -2720,7 +2801,7 @@ put_method(Method *m) } s = g_strdup (m->id); - g_strup (s); + gob_strup (s); out_printf(out, "\tg_signal_emitv (___param_values,\n" "\t\tobject_signals[%s_SIGNAL],\n" @@ -2729,22 +2810,39 @@ put_method(Method *m) g_free (s); + clear_signal_args (m); + if (strcmp (m->gtktypes->data, "NONE") != 0) { char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE)); char *getfunc; + /* Hack because glib is very very braindead */ + gboolean do_dup = + (strcmp ((char *)m->gtktypes->data, "STRING") == 0 || + strcmp ((char *)m->gtktypes->data, "BOXED") == 0 || + strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 || + strcmp ((char *)m->gtktypes->data, "PARAM") == 0); if (strcmp (m->gtktypes->data, "UNICHAR") == 0) /* hack because glib is braindamaged */ getfunc = g_strdup ("g_value_get_uint"); else - getfunc = g_strdup_printf ("g_value_get_%s", + getfunc = g_strdup_printf ("g_value_%s_%s", + do_dup ? "dup" : "get", (char *)m->gtktypes->data); - g_strdown (getfunc); + gob_strdown (getfunc); if (cast == NULL) cast = get_type (m->mtype, TRUE); - out_printf (out, "\n\treturn (%s) %s (&___return_val);\n", + out_printf (out, + "\n\t{\n" + "\t\t"); + print_type (out, m->mtype, TRUE); + out_printf (out, + " ___ret = (%s) %s (&___return_val);\n" + "\t\tg_value_unset (&___return_val);\n" + "\t\treturn ___ret;\n" + "\t}\n", cast, getfunc); g_free (cast); @@ -2757,8 +2855,8 @@ put_method(Method *m) 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); + m, FALSE, FALSE, TRUE, TRUE, FALSE); + print_method_body(m, FALSE, TRUE); /* the outfile line was added above */ break; case VIRTUAL_METHOD: @@ -2766,10 +2864,10 @@ put_method(Method *m) out_addline_infile(out, m->line_no); if(m->scope==PRIVATE_SCOPE) print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); else /* PUBLIC, PROTECTED */ print_method(out, "", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE); + m, FALSE, FALSE, TRUE, FALSE, FALSE); out_addline_outfile(out); out_printf(out, "{\n" "\t%sClass *klass;\n", typebase); @@ -2815,8 +2913,8 @@ put_method(Method *m) 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); + m, FALSE, FALSE, TRUE, TRUE, FALSE); + print_method_body(m, FALSE, TRUE); /* the outfile line was added above */ break; case OVERRIDE_METHOD: @@ -2826,11 +2924,11 @@ put_method(Method *m) 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); + m, FALSE, FALSE, FALSE, TRUE, FALSE); g_free(s); out_addline_outfile(out); s = replace_sep(m->otype, '_'); - g_strup(s); + gob_strup (s); args = get_arg_names_for_macro(m); if(is_void) { out_printf(out, "#define PARENT_HANDLER(%s) \\\n" @@ -2850,7 +2948,7 @@ put_method(Method *m) } g_free(args); g_free(s); - print_method_body(m, TRUE); + print_method_body(m, TRUE, TRUE); /* the outfile line was added above */ out_printf(out, "#undef PARENT_HANDLER\n"); break; @@ -2865,18 +2963,18 @@ open_files(void) char *outfile, *outfileh, *outfileph; if ( ! for_cpp) - outfile = g_strconcat (filebase, ".c", NULL); + outfile = g_strconcat (fullfilebase, ".c", NULL); else - outfile = g_strconcat (filebase, ".cc", NULL); + outfile = g_strconcat (fullfilebase, ".cc", NULL); if (no_touch_headers) - outfileh = g_strconcat ("#gob#", filebase, ".h#gob#", NULL); + outfileh = g_strconcat (fullfilebase, ".h#gob#", NULL); else - outfileh = g_strconcat (filebase, ".h", NULL); + outfileh = g_strconcat (fullfilebase, ".h", NULL); if ((privates > 0 || protecteds > 0 || private_header == PRIVATE_HEADER_ALWAYS) && private_header != PRIVATE_HEADER_NEVER) - outfileph = g_strconcat (filebase, "-private.h", NULL); + outfileph = g_strconcat (fullfilebase, "-private.h", NULL); else outfileph = NULL; @@ -2884,7 +2982,7 @@ open_files(void) if (no_write) { devnull = fopen ("/dev/null", "w"); if (devnull == NULL) - g_error ("Cannot open null device"); + error_print (GOB_ERROR, 0, "Cannot open null device"); out = devnull; outh = devnull; if (outfileph != NULL) @@ -2892,15 +2990,21 @@ open_files(void) } else { out = fopen (outfile, "w"); if (out == NULL) { - g_error ("Cannot open outfile: %s", outfile); + error_printf (GOB_ERROR, 0, + "Cannot open outfile: %s", outfile); } outh = fopen (outfileh, "w"); - if (outh == NULL) - g_error ("Cannot open outfile: %s", outfileh); + if (outh == NULL) { + error_printf (GOB_ERROR, 0, + "Cannot open outfile: %s", outfileh); + } if (outfileph != NULL) { outph = fopen (outfileph, "w"); - if (outph == NULL) - g_error ("Cannot open outfile: %s", outfileh); + if (outph == NULL) { + error_printf (GOB_ERROR, 0, + "Cannot open outfile: %s", + outfileph); + } } } } @@ -2940,7 +3044,7 @@ put_argument_nongnu_wrappers (Class *c) } aname = g_strdup (name); - g_strup (aname); + gob_strup (aname); if (atype != NULL) cast = get_type (atype, TRUE); @@ -3006,7 +3110,7 @@ put_argument_gnu_wrappers(Class *c) } aname = g_strdup (name); - g_strup (aname); + gob_strup (aname); if (atype != NULL) cast = get_type (atype, TRUE); @@ -3016,11 +3120,11 @@ put_argument_gnu_wrappers(Class *c) if (cast != NULL) { if (set) out_printf (outh, "#define %s_PROP_%s(arg) \t" - "\"%s\",({%sz = (arg); z;})\n", + "\"%s\", __extension__ ({%sz = (arg); z;})\n", macrobase, aname, name, cast); if (get) out_printf (outh, "#define %s_GET_PROP_%s(arg)\t" - "\"%s\",({%s*z = (arg); z;})\n", + "\"%s\", __extension__ ({%s*z = (arg); z;})\n", macrobase, aname, name, cast); } else { if (set) @@ -3166,7 +3270,7 @@ print_class_block(Class *c) " * Main object structure\n" " */\n"); s = replace_sep (c->otype, '_'); - g_strup (s); + gob_strup (s); out_printf (outh, "#ifndef __TYPEDEF_%s__\n" "#define __TYPEDEF_%s__\n", s, s); g_free (s); @@ -3281,7 +3385,7 @@ print_class_block(Class *c) " */\n"); if ( ! overrode_get_type) { - out_printf (outh, "GType\t%s_get_type\t(void);", funcbase); + out_printf (outh, "GType\t%s_get_type\t(void);\n", funcbase); } for(li = c->nodes; li != NULL; li = li->next) { @@ -3343,13 +3447,8 @@ print_class_block(Class *c) add_enums (c); 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"); - } - make_method_nongnu_aliases(c); + out_printf (out, "/* Short form macros */\n"); + make_method_aliases (c); } add_interface_inits (c); @@ -3423,6 +3522,23 @@ print_useful_macros(void) out_printf (out, "#define selfp (self->_priv)\n\n"); } +static void +print_more_useful_macros (void) +{ + if (no_gnu) { + out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n"); + out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n"); + } else { + out_printf (out, "#ifdef G_LIKELY\n"); + out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n"); + out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n"); + out_printf (out, "#else /* ! G_LIKELY */\n"); + out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n"); + out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n"); + out_printf (out, "#endif /* G_LIKELY */\n"); + } +} + static void print_file_comments(void) { @@ -3488,7 +3604,7 @@ print_header_prefixes(void) char *p; p = replace_sep(((Class *)class)->otype, '_'); - g_strup(p); + gob_strup (p); out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p); if(outph) out_printf(outph, "#ifndef __%s_PRIVATE_H__\n" @@ -3569,7 +3685,7 @@ print_enum (EnumDef *enode) char *str; funcprefix = replace_sep (enode->etype, '_'); - g_strdown (funcprefix); + gob_strdown (funcprefix); out_printf (out, "static const GEnumValue _%s_values[] = {\n", funcprefix); type = remove_sep (enode->etype); @@ -3579,7 +3695,7 @@ print_enum (EnumDef *enode) for (li = enode->values; li != NULL; li = li->next) { EnumValue *value = li->data; char *p; - char *sname = g_strdown (g_strdup (value->name)); + char *sname = gob_strdown (g_strdup (value->name)); while ((p = strchr (sname, '_')) != NULL) *p = '-'; @@ -3592,7 +3708,7 @@ print_enum (EnumDef *enode) else out_printf (outh, "\n"); - out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n", + out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n", enode->prefix, value->name, enode->prefix, value->name, sname); @@ -3615,7 +3731,7 @@ print_enum (EnumDef *enode) "GType\n%s_get_type (void)\n" "{\n" "\tstatic GType type = 0;\n" - "\tif (type == 0)\n" + "\tif ___GOB_UNLIKELY(type == 0)\n" "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n" "\treturn type;\n" "}\n\n", @@ -3635,7 +3751,7 @@ print_flags (Flags *fnode) int i; funcprefix = replace_sep (fnode->ftype, '_'); - g_strdown (funcprefix); + gob_strdown (funcprefix); out_printf (out, "static const GFlagsValue _%s_values[] = {\n", funcprefix); type = remove_sep (fnode->ftype); @@ -3645,7 +3761,7 @@ print_flags (Flags *fnode) for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) { const char *name = li->data; char *p; - char *sname = g_strdown (g_strdup (name)); + char *sname = gob_strdown (g_strdup (name)); while ((p = strchr (sname, '_')) != NULL) *p = '-'; @@ -3657,7 +3773,7 @@ print_flags (Flags *fnode) else out_printf (outh, "\n"); - out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n", + out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n", fnode->prefix, name, fnode->prefix, name, sname); @@ -3680,7 +3796,7 @@ print_flags (Flags *fnode) "GType\n%s_get_type (void)\n" "{\n" "\tstatic GType type = 0;\n" - "\tif (type == 0)\n" + "\tif ___GOB_UNLIKELY(type == 0)\n" "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n" "\treturn type;\n" "}\n\n", @@ -3699,7 +3815,7 @@ print_error (Error *enode) char *str; funcprefix = replace_sep (enode->etype, '_'); - g_strdown (funcprefix); + gob_strdown (funcprefix); out_printf (out, "static const GEnumValue _%s_values[] = {\n", funcprefix); type = remove_sep (enode->etype); @@ -3709,7 +3825,7 @@ print_error (Error *enode) for (li = enode->values; li != NULL; li = li->next) { const char *name = li->data; char *p; - char *sname = g_strdown (g_strdup (name)); + char *sname = gob_strdown (g_strdup (name)); while ((p = strchr (sname, '_')) != NULL) *p = '-'; @@ -3720,7 +3836,7 @@ print_error (Error *enode) else out_printf (outh, "\n"); - out_printf (out, "\t{ %s_%s, \"%s_%s\", \"%s\" },\n", + out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n", enode->prefix, name, enode->prefix, name, sname); @@ -3743,7 +3859,7 @@ print_error (Error *enode) "GType\n%s_get_type (void)\n" "{\n" "\tstatic GType type = 0;\n" - "\tif (type == 0)\n" + "\tif ___GOB_UNLIKELY(type == 0)\n" "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n" "\treturn type;\n" "}\n\n", @@ -3753,7 +3869,7 @@ print_error (Error *enode) out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix); str = replace_sep (enode->etype, '-'); - g_strdown (str); + gob_strdown (str); out_printf (out, "GQuark\n%s_quark (void)\n" @@ -3788,6 +3904,8 @@ generate_outfiles(void) print_includes(); + print_more_useful_macros (); + for (li = nodes; li != NULL; li = li->next) { Node *node = li->data; if (node->type == CCODE_NODE) { @@ -3829,10 +3947,10 @@ print_help(void) "really changed\n" "\t--always-private-header Always create a private header " "file,\n" - "\t even if it would be empty " - "[default]\n" + "\t even if it would be empty\n" "\t--ondemand-private-header Create private header only when " "needed\n" + "\t [default]\n" "\t--no-private-header Don't create a private header, " "put private\n" "\t structure and protected " @@ -3851,7 +3969,9 @@ print_help(void) "\t--no-lines Don't print '#line' to output\n" "\t--no-self-alias Don't create self type and macro " "aliases\n" - "\t--no-kill-underscores Ignored for compatibility\n"); + "\t--no-kill-underscores Ignored for compatibility\n" + "\t-o,--output-dir The directory where output " + "should be placed\n"); } static void @@ -3953,6 +4073,21 @@ parse_options(int argc, char *argv[]) use_m4_clean=TRUE; m4_opts = TRUE; m4_commandline=g_strdup(M4_COMMANDLINE); + } else if (strcmp (argv[i], "-o") == 0 || + strcmp (argv[i], "--output-dir") == 0) { + if (i+1 < argc) { + output_dir = g_strdup (argv[i+1]); + i++; + } else { + output_dir = NULL; + } + } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 || + strncmp (argv[i], + "--output-dir=", + strlen ("--output-dir=")) == 0) { + char *p = strchr (argv[i], '='); + g_assert (p != NULL); + output_dir = g_strdup (p+1); } else if(strcmp(argv[i], "--")==0) { /*further arguments are files*/ no_opts = TRUE; @@ -4005,8 +4140,8 @@ parse_options(int argc, char *argv[]) static void compare_and_move_header(void) { - char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL); - char *hf = g_strconcat(filebase, ".h", NULL); + char *hfnew = g_strconcat(fullfilebase, ".h#gob#", NULL); + char *hf = g_strconcat(fullfilebase, ".h", NULL); struct stat s; if(stat(hf, &s) == 0) { char *s; @@ -4059,7 +4194,7 @@ main(int argc, char *argv[]) /* This is where parsing is done */ /*yydebug = 1;*/ if(yyparse() != 0) - g_error("Parsing errors, quitting"); + error_print (GOB_ERROR, 0, "Parsing errors, quitting"); /* close input file */ if(use_m4) pclose(yyin); @@ -4067,7 +4202,7 @@ main(int argc, char *argv[]) yyin=stdin; if( ! class) - error_print(GOB_ERROR, 0, " no class defined"); + error_print (GOB_ERROR, 0, "no class defined"); exit_on_error = FALSE; @@ -4108,6 +4243,7 @@ main(int argc, char *argv[]) check_property_types ((Class *)class); check_argument_types ((Class *)class); check_func_arg_checks ((Class *)class); + check_for_class_destructors ((Class *)class); exit_on_error = TRUE;