Re: patch allowing to add GCC attributes to methods
Jean-Yves Lefort <[email protected]> Tue, 29 Jan 2008 01:39:26 +0100
| Newsgroups | gmane.comp.gnome.devtools.gob.general |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format. [email protected] Content-Type: multipart/signed; protocol="application/pgp-signature"; micalg="PGP-SHA1"; boundary="Signature=_Tue__29_Jan_2008_01_39_26_+0100_wxW+IoBpsfHR4Hxx" --Signature=_Tue__29_Jan_2008_01_39_26_+0100_wxW+IoBpsfHR4Hxx Content-Type: multipart/mixed; boundary="Multipart=_Tue__29_Jan_2008_01_39_26_+0100_Em=asTXAOQy259Ny" --Multipart=_Tue__29_Jan_2008_01_39_26_+0100_Em=asTXAOQy259Ny Content-Type: text/plain; charset=US-ASCII Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, 28 Jan 2008 18:10:20 +0100 Jean-Yves Lefort <[email protected]> wrote: > The attached patch allows to add GCC attributes to methods, using a > syntax borrowed from C#. I've fixed my other patch (gob2-2.0.15-gobject-overrides.diff), so I'm attaching the new unified patch. --=20 Jean-Yves Lefort <[email protected]> --Multipart=_Tue__29_Jan_2008_01_39_26_+0100_Em=asTXAOQy259Ny Content-Type: text/x-diff; name="gob2-2.0.15-gobject-overrides-and-attr.diff" Content-Disposition: attachment; filename="gob2-2.0.15-gobject-overrides-and-attr.diff" Content-Transfer-Encoding: quoted-printable --- src/lexer.l.orig 2007-09-28 06:26:49.000000000 +0200 +++ src/lexer.l 2008-01-29 01:25:46.000000000 +0100 @@ -31,6 +31,7 @@ #include "main.h" #include "util.h" =20 +static int bracket_depth =3D 0; static int parenth_depth =3D 0; static int before_comment /* New flex is on drugs */ @@ -102,6 +103,7 @@ =20 %x COMMENT %x C_CODE +%x ATTR_CODE %x CODE_STRING %x CLASS_CODE %x CLASS_STRING @@ -267,7 +269,7 @@ add_to_cbuf(yytext); } =20 -<C_CODE>\/\/.*$ { add_to_cbuf(yytext); /*comment, ignore*/ } +<C_CODE,ATTR_CODE>\/\/.*$ { add_to_cbuf(yytext); /*comment, ignore*/ } <CLASS_CODE>\/\/.*$ { ; /*comment, ignore*/ } <CLASS_CODE_I>\/\/.*$ { ; /*comment, ignore*/ } <PROPERTY_CODE_I>\/\/.*$ { ; /*comment, ignore*/ } @@ -277,20 +279,25 @@ BEGIN(COMMENT); before_comment =3D C_CODE; } +<ATTR_CODE>\/\* { + add_to_cbuf(yytext); + BEGIN(COMMENT); + before_comment =3D ATTR_CODE; +} <CLASS_CODE>\/\* {BEGIN(COMMENT); before_comment =3D CLASS_CODE; } <CLASS_CODE_I>\/\* {BEGIN(COMMENT); before_comment =3D CLASS_CODE_I; } <PROPERTY_CODE_I>\/\* {BEGIN(COMMENT); before_comment =3D PROPERTY_CODE_I;= } <COMMENT>\*\/ { - if(before_comment =3D=3D C_CODE) add_to_cbuf(yytext); + if(before_comment =3D=3D C_CODE || before_comment =3D=3D ATTR_CODE) add_t= o_cbuf(yytext); BEGIN(before_comment); } <COMMENT>. { /* comment, ignore */ - if(before_comment =3D=3D C_CODE) add_to_cbuf(yytext); + if(before_comment =3D=3D C_CODE || before_comment =3D=3D ATTR_CODE) add_t= o_cbuf(yytext); } <COMMENT>\n { /* comment, ignore */ - if(before_comment =3D=3D C_CODE) add_to_cbuf(yytext); + if(before_comment =3D=3D C_CODE || before_comment =3D=3D ATTR_CODE) add_t= o_cbuf(yytext); } =20 ^\%(a|all)\{ { @@ -353,14 +360,14 @@ return code_type; } =20 -<C_CODE>\'\{\' { add_to_cbuf(yytext); } -<C_CODE>\'\\\{\' { add_to_cbuf(yytext); } -<C_CODE>\'\}\' { add_to_cbuf(yytext); } -<C_CODE>\'\\\}\' { add_to_cbuf(yytext); } -<C_CODE>\'\"\' { add_to_cbuf(yytext); } -<C_CODE>\'\\\"\' { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\'\{\' { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\'\\\{\' { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\'\}\' { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\'\\\}\' { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\'\"\' { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\'\\\"\' { add_to_cbuf(yytext); } =09 -<C_CODE>\\. { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\\. { add_to_cbuf(yytext); } =20 =20 <C_CODE>\" { @@ -368,6 +375,11 @@ before_string =3D C_CODE; add_to_cbuf(yytext); } +<ATTR_CODE>\" { + BEGIN(CODE_STRING); + before_string =3D ATTR_CODE; + add_to_cbuf(yytext); + } <PROPERTY_CODE_I>\" { BEGIN(CODE_STRING); before_string =3D PROPERTY_CODE_I; @@ -391,6 +403,10 @@ parenth_depth++; add_to_cbuf(yytext); } +<ATTR_CODE>\[ { + bracket_depth++; + add_to_cbuf(yytext); + } <C_CODE>\} { parenth_depth--; if(parenth_depth<0) { @@ -403,9 +419,21 @@ } add_to_cbuf(yytext); } +<ATTR_CODE>\] { + bracket_depth--; + if(bracket_depth<0) { + REJECT; + } else if(bracket_depth=3D=3D0) { + BEGIN(CLASS_CODE_I); + yylval.cbuf =3D cbuf; + cbuf =3D NULL; + return CCODE; + } + add_to_cbuf(yytext); + } =20 -<C_CODE>. { add_to_cbuf(yytext); } -<C_CODE>\n { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>. { add_to_cbuf(yytext); } +<C_CODE,ATTR_CODE>\n { add_to_cbuf(yytext); } =20 class { static int found_classes =3D 0; @@ -588,12 +616,12 @@ =20 <CLASS_CODE_I>(\[[0-9]*\]|\[[A-Za-z_][A-Za-z0-9_]*\])+ { yylval.id =3D g_strdup(yytext); - return ARRAY_DIM; + return ARRAY_DIM_OR_ATTR; } <CLASS_CODE_I>:[0-9]+ { /* cheat for bitfield */ yylval.id =3D g_strdup(yytext); - return ARRAY_DIM; + return BITFIELD; } <CLASS_CODE>\{ { BEGIN(CLASS_CODE_I); @@ -612,6 +640,13 @@ BEGIN(INITIAL); return '}'; } +<CLASS_CODE_I>\[ { + BEGIN(ATTR_CODE); + bracket_depth=3D1; + yylval.line =3D line_no; + clear_cbuf(); + return '['; + } =20 <CLASS_CODE,CLASS_CODE_I,INITIAL,PROPERTY_CODE,PROPERTY_CODE_I>[\f\t ] ; = /*ignore*/ =20 --- src/main.c.orig 2007-10-17 16:49:04.000000000 +0200 +++ src/main.c 2008-01-29 01:25:46.000000000 +0100 @@ -92,11 +92,16 @@ static gboolean special_array[SPECIAL_LAST] =3D {0}; static gboolean any_special =3D FALSE; =20 +static gboolean need_constructor =3D FALSE; +static Method * user_constructor =3D NULL; + static gboolean need_dispose =3D FALSE; static Method * dispose_handler =3D NULL; +static Method * user_dispose_method =3D NULL; =20 static gboolean need_finalize =3D FALSE; static Method * finalize_handler =3D NULL; +static Method * user_finalize_method =3D NULL; =20 FILE *out =3D NULL; FILE *outh =3D NULL; @@ -189,21 +194,25 @@ g_free(s); } =20 - -static void -print_method (FILE *fp, - const char *typeprefix, - const char *nameprefix, - const char *subnameprefix, - const char *namepostfix, - const char *afterargs, - const char *postfix, - const Method *m, - gboolean one_arg_per_line, - gboolean no_funcbase, - gboolean kill_underscore, - gboolean first_unused, - gboolean fake_names) +typedef enum +{ + PRINT_METHOD_ONE_ARG_PER_LINE =3D 1 << 0, + PRINT_METHOD_NO_FUNCBASE =3D 1 << 1, + PRINT_METHOD_FIRST_UNUSED =3D 1 << 2, + PRINT_METHOD_FAKE_NAMES =3D 1 << 3, + PRINT_METHOD_NO_ATTR =3D 1 << 4 +} PrintMethodFlags; + +static void +print_method2 (FILE *fp, + const char *typeprefix, + const char *nameprefix, + const char *subnameprefix, + const char *namepostfix, + const char *afterargs, + const char *postfix, + const Method *m, + PrintMethodFlags flags) { GList *li; const char *id; @@ -213,7 +222,7 @@ =20 id =3D m->id; =20 - if(no_funcbase) + if ((flags & PRINT_METHOD_NO_FUNCBASE) !=3D 0) out_printf(fp, "%s%s%s%s(", nameprefix, subnameprefix, id, namepostfix);=20 else @@ -229,19 +238,19 @@ if ( ! no_gnu && ! for_cpp && /* g++ has a cow with this */ li =3D=3D m->args && - first_unused) { + (flags & PRINT_METHOD_FIRST_UNUSED) !=3D 0) { unused =3D " G_GNUC_UNUSED"; } =20 print_type(fp, arg->atype, FALSE); - if (fake_names) + if ((flags & PRINT_METHOD_FAKE_NAMES) !=3D 0) out_printf (fp, "___fake___"); if(li->next) 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" : " "); + (flags & PRINT_METHOD_ONE_ARG_PER_LINE) !=3D 0 ? "\n\t\t\t\t\t" : = " "); else out_printf(fp, "%s%s%s", arg->name, arg->atype->postfix ? @@ -250,11 +259,54 @@ } if(m->vararg) out_printf(fp, ",%s...", - one_arg_per_line ? "\n\t\t\t\t\t" : " ");=20 + (flags & PRINT_METHOD_ONE_ARG_PER_LINE) !=3D 0 ? "\n\t\t\t\t\t" : "= ");=20 } else { out_printf(fp, "void");=20 } - out_printf(fp, "%s)%s", afterargs, postfix);=20 + + out_printf(fp, "%s)", afterargs); + + if (m->attr && (flags & PRINT_METHOD_NO_ATTR) =3D=3D 0) + out_printf(fp, " %s", m->attr); + + out_printf(fp, "%s", postfix); +} + +static void +print_method (FILE *fp, + const char *typeprefix, + const char *nameprefix, + const char *subnameprefix, + const char *namepostfix, + const char *afterargs, + const char *postfix, + const Method *m, + gboolean one_arg_per_line, + gboolean no_funcbase, + gboolean kill_underscore, + gboolean first_unused, + gboolean fake_names) +{ + PrintMethodFlags flags =3D 0; + + if (one_arg_per_line) + flags |=3D PRINT_METHOD_ONE_ARG_PER_LINE; + if (no_funcbase) + flags |=3D PRINT_METHOD_NO_FUNCBASE; + if (first_unused) + flags |=3D PRINT_METHOD_FIRST_UNUSED; + if (fake_names) + flags |=3D PRINT_METHOD_FAKE_NAMES; + + print_method2(fp, + typeprefix, + nameprefix, + subnameprefix, + namepostfix, + afterargs, + postfix, + m, + flags); } =20 static gboolean @@ -269,6 +321,9 @@ =09 if(m->method =3D=3D INIT_METHOD || m->method =3D=3D CLASS_INIT_METHOD || + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD || m->method =3D=3D OVERRIDE_METHOD) continue; =20 @@ -291,6 +346,9 @@ =09 if(m->method =3D=3D INIT_METHOD || m->method =3D=3D CLASS_INIT_METHOD || + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD || m->method =3D=3D OVERRIDE_METHOD) continue; =20 @@ -330,6 +388,9 @@ =09 if(m->method =3D=3D INIT_METHOD || m->method =3D=3D CLASS_INIT_METHOD || + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD || m->method =3D=3D OVERRIDE_METHOD) continue; =20 @@ -371,11 +432,13 @@ =20 /* if a signal mark it as such */ if(m->method !=3D VIRTUAL_METHOD) - print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n", - m, FALSE, TRUE, TRUE, FALSE, FALSE); + print_method2(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n", + m, PRINT_METHOD_NO_FUNCBASE | + PRINT_METHOD_NO_ATTR); else - print_method(outh, "\t", "(* ", "", ") ", "", ";\n", - m, FALSE, TRUE, TRUE, FALSE, FALSE); + print_method2(outh, "\t", "(* ", "", ") ", "", ";\n", + m, PRINT_METHOD_NO_FUNCBASE | + PRINT_METHOD_NO_ATTR); } =20 static void @@ -422,8 +485,11 @@ "\"%s\"," "(GCallback) __extension__ ({", funcbase, m->id, macrobase, typebase, m->id); - print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ", - " =3D (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE); + print_method2 (outh, "", "(* ___", "", ") ", ", gpointer ___data ", + " =3D (func); ", m, + PRINT_METHOD_NO_FUNCBASE + | PRINT_METHOD_FAKE_NAMES + | PRINT_METHOD_NO_ATTR); out_printf (outh, "___%s; }), (data))\n", m->id); =20 /* connect_after */ @@ -433,8 +499,11 @@ "\"%s\"," "(GCallback) __extension__ ({", funcbase, m->id, macrobase, typebase, m->id); - print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ", - " =3D (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE); + print_method2 (outh, "", "(* ___", "", ") ", ", gpointer ___data ", + " =3D (func); ", m, + PRINT_METHOD_NO_FUNCBASE + | PRINT_METHOD_FAKE_NAMES + | PRINT_METHOD_NO_ATTR); out_printf (outh, "___%s; }), (data))\n", m->id); =20 /* connect_data */ @@ -445,8 +514,11 @@ "\"%s\"," "(GCallback) __extension__ ({", funcbase, m->id, macrobase, typebase, m->id); - print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ", - " =3D (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE); + print_method2 (outh, "", "(* ___", "", ") ", ", gpointer ___data ", + " =3D (func); ", m, + PRINT_METHOD_NO_FUNCBASE + | PRINT_METHOD_FAKE_NAMES + | PRINT_METHOD_NO_ATTR); out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(fl= ags))\n", m->id); } } @@ -526,9 +598,9 @@ m->method =3D=3D SIGNAL_FIRST_METHOD || m->method =3D=3D VIRTUAL_METHOD) { if(m->cbuf) - print_method(out, - "static ", "___real_", "", " ", "", ";\n", - m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method2(out, + "static ", "___real_", "", " ", "", ";\n", + m, PRINT_METHOD_NO_ATTR); } /* no else, here, it might still have a private prototype, it's not * exclusive */ @@ -537,15 +609,16 @@ m->cbuf)) { /* add unique ID */ char *s =3D g_strdup_printf("___%x_", (guint)m->unique_id); - print_method(out, "static ", s, "", " ", "", - no_gnu?";\n":" G_GNUC_UNUSED;\n", + print_method(out, "static ", s, "", " ", "", ";\n", m, FALSE, FALSE, FALSE, FALSE, FALSE); g_free(s); } else if(m->scope =3D=3D PRIVATE_SCOPE || m->method =3D=3D INIT_METHOD || - m->method =3D=3D CLASS_INIT_METHOD) { - print_method(out, "static ", "", "", " ", "", - no_gnu?";\n":" G_GNUC_UNUSED;\n", + m->method =3D=3D CLASS_INIT_METHOD || + m->method =3D=3D CONSTRUCTOR_METHOD || + m->method =3D=3D DISPOSE_METHOD || + m->method =3D=3D FINALIZE_METHOD) { + print_method(out, "static ", "", "", " ", "", ";\n", m, FALSE, FALSE, TRUE, FALSE, FALSE); } } @@ -629,66 +702,68 @@ } } =20 -static void -find_dispose(const Class *cl) +static Method * +find_method(const Class *cl, int method, const char *id) { GList *li; =20 - dispose_handler =3D NULL; for(li=3Dcl->nodes;li;li=3Dg_list_next(li)) { Node *n =3D li->data; if(n->type =3D=3D METHOD_NODE) { Method *m =3D (Method *)n; - if(m->method =3D=3D OVERRIDE_METHOD && - strcmp(m->id, "dispose")=3D=3D0) { - if(strcmp(m->otype, "G:Object") !=3D 0) { - error_print(GOB_ERROR, m->line_no, - "dispose method override " - "of class other then " - "G:Object"); - } - if(g_list_length(m->args) !=3D 1) { - error_print(GOB_ERROR, m->line_no, - "dispose method override " - "with more then one " - "parameter"); - } - dispose_handler =3D m; - break; - } + if (m->method =3D=3D method + && (id =3D=3D NULL || strcmp(m->id, id)=3D=3D0)) + return m; } } + + return NULL; } =20 static void -find_finalize(const Class *cl) +find_constructor(const Class *cl) { - GList *li; + user_constructor =3D find_method(cl, CONSTRUCTOR_METHOD, NULL); +} =20 - finalize_handler =3D NULL; - for(li=3Dcl->nodes;li;li=3Dg_list_next(li)) { - Node *n =3D li->data; - if(n->type =3D=3D METHOD_NODE) { - Method *m =3D (Method *)n; - if(m->method =3D=3D OVERRIDE_METHOD && - strcmp(m->id, "finalize")=3D=3D0) { - if(strcmp(m->otype, "G:Object") !=3D 0) { - error_print(GOB_ERROR, m->line_no, - "finalize method override " - "of class other then " - "G:Object"); - } - if(g_list_length(m->args) !=3D 1) { - error_print(GOB_ERROR, m->line_no, - "finalize method override " - "with more then one " - "parameter"); - } - finalize_handler =3D m; - break; - } - } +static void +find_dispose(const Class *cl) +{ + dispose_handler =3D find_method(cl, OVERRIDE_METHOD, "dispose"); + if (dispose_handler !=3D NULL) { + if(strcmp(dispose_handler->otype, "G:Object") !=3D 0) + error_print(GOB_ERROR, dispose_handler->line_no, + "dispose method override " + "of class other then " + "G:Object"); + if(g_list_length(dispose_handler->args) !=3D 1) + error_print(GOB_ERROR, dispose_handler->line_no, + "dispose method override " + "with more then one " + "parameter"); + } + + user_dispose_method =3D find_method(cl, DISPOSE_METHOD, NULL); +} + +static void +find_finalize(const Class *cl) +{ + finalize_handler =3D find_method(cl, OVERRIDE_METHOD, "finalize"); + if (finalize_handler !=3D NULL) { + if(strcmp(finalize_handler->otype, "G:Object") !=3D 0) + error_print(GOB_ERROR, finalize_handler->line_no, + "finalize method override " + "of class other then " + "G:Object"); + if(g_list_length(finalize_handler->args) !=3D 1) + error_print(GOB_ERROR, finalize_handler->line_no, + "finalize method override " + "with more then one " + "parameter"); } + + user_finalize_method =3D find_method(cl, FINALIZE_METHOD, NULL); } =20 =20 @@ -2118,6 +2193,33 @@ } =20 static void +add_constructor (Class *c) +{ + out_printf(out, "\nstatic GObject *\n" + "___constructor (GType type, guint n_construct_properties, GObjectCon= structParam *construct_properties)\n" + "{\n"); + out_printf(out, + "#define __GOB_FUNCTION__ \"%s::constructor\"\n", + c->otype); + + out_printf(out, "\tGObject *obj_self;\n"); + out_printf(out, "\t%s *self;\n", typebase); + + out_printf(out, "\tobj_self =3D G_OBJECT_CLASS (parent_class)->constructo= r (type, n_construct_properties, construct_properties);\n"); + out_printf(out, "\tself =3D %s (obj_self);\n", macrobase); + + if (user_constructor->line_no > 0) + out_addline_infile (out, user_constructor->line_no); + out_printf (out, "\t%s_constructor (self);\n", funcbase); + if (user_constructor->line_no > 0) + out_addline_outfile (out); + + out_printf(out, "\treturn obj_self;\n"); + out_printf(out, "}\n" + "#undef __GOB_FUNCTION__\n\n"); +} + +static void add_dispose (Class *c) { out_printf(out, "\nstatic void\n" @@ -2127,7 +2229,7 @@ "#define __GOB_FUNCTION__ \"%s::dispose\"\n", c->otype); =20 - if (unreftors > 0) { + if (unreftors > 0 || user_dispose_method !=3D NULL) { out_printf (out, "\t%s *self%s =3D %s (obj_self);\n", typebase, ! no_gnu ? " G_GNUC_UNUSED" : "", @@ -2143,6 +2245,14 @@ if (dispose_handler->line_no > 0) out_addline_outfile (out); } else { + if (user_dispose_method !=3D NULL) { + if (user_dispose_method->line_no > 0) + out_addline_infile (out, user_dispose_method->line_no); + out_printf (out, "\t%s_dispose (self);\n", funcbase); + if (user_dispose_method->line_no > 0) + out_addline_outfile (out); + } + out_printf (out, "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n" "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n"); @@ -2178,7 +2288,8 @@ c->otype); =20 if (privates > 0 || - destructors > 0) { + destructors > 0 || + user_finalize_method !=3D NULL) { const char *unused =3D ""; if ( ! no_gnu) unused =3D " G_GNUC_UNUSED"; @@ -2202,6 +2313,14 @@ if(finalize_handler->line_no > 0) out_addline_outfile(out); } else { + if (user_finalize_method !=3D NULL) { + if (user_finalize_method->line_no > 0) + out_addline_infile (out, user_finalize_method->line_no); + out_printf (out, "\t%s_finalize (self);\n", funcbase); + if (user_finalize_method->line_no > 0) + out_addline_outfile (out); + } + out_printf(out, "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n" "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"); @@ -2333,6 +2452,7 @@ if (set_properties > 0 || get_properties > 0 || signals > 0 || + need_constructor || need_dispose || need_finalize) { out_printf(out, @@ -2381,6 +2501,9 @@ =20 /* if there are no handlers for these things, we * need to set them up here */ + if(need_constructor) + out_printf(out, "\tg_object_class->constructor " + "=3D ___constructor;\n"); if(need_dispose && !dispose_handler) out_printf(out, "\tg_object_class->dispose " "=3D ___dispose;\n"); @@ -2831,11 +2954,11 @@ if(m->line_no > 0) out_addline_infile(out, m->line_no); if(m->scope =3D=3D PRIVATE_SCOPE) - print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method2(out, "static ", "\n", "", " ", "", "\n", + m, PRINT_METHOD_NO_ATTR); else /* PUBLIC, PROTECTED */ - print_method(out, "", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method2(out, "", "\n", "", " ", "", "\n", + m, PRINT_METHOD_NO_ATTR); print_method_body(m, TRUE, TRUE); /* the outfile line was added above */ break; @@ -2844,11 +2967,11 @@ if(m->line_no > 0) out_addline_infile(out, m->line_no); if(m->scope =3D=3D PRIVATE_SCOPE) - print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method2(out, "static ", "\n", "", " ", "", "\n", + m, PRINT_METHOD_NO_ATTR); else /* PUBLIC, PROTECTED */ - print_method(out, "", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method2(out, "", "\n", "", " ", "", "\n", + m, PRINT_METHOD_NO_ATTR); out_addline_outfile (out); =20 out_printf (out, "{\n"); @@ -2966,8 +3089,8 @@ break; if(m->line_no > 0) out_addline_infile(out, m->line_no); - print_method(out, "static ", "\n___real_", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, TRUE, FALSE); + print_method2(out, "static ", "\n___real_", "", " ", "", "\n", + m, PRINT_METHOD_NO_ATTR); print_method_body(m, FALSE, TRUE); /* the outfile line was added above */ break; @@ -2975,11 +3098,11 @@ if(m->line_no > 0) out_addline_infile(out, m->line_no); if(m->scope=3D=3DPRIVATE_SCOPE) - print_method(out, "static ", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method2(out, "static ", "\n", "", " ", "", "\n", + m, PRINT_METHOD_NO_ATTR); else /* PUBLIC, PROTECTED */ - print_method(out, "", "\n", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method2(out, "", "\n", "", " ", "", "\n", + m, PRINT_METHOD_NO_ATTR); out_addline_outfile(out); out_printf(out, "{\n" "\t%sClass *klass;\n", typebase); @@ -3024,8 +3147,9 @@ break; if(m->line_no > 0) out_addline_infile(out, m->line_no); - print_method(out, "static ", "\n___real_", "", " ", "", "\n", - m, FALSE, FALSE, TRUE, TRUE, FALSE); + print_method2(out, "static ", "\n___real_", "", " ", "", "\n", + m, PRINT_METHOD_FIRST_UNUSED + | PRINT_METHOD_NO_ATTR); print_method_body(m, FALSE, TRUE); /* the outfile line was added above */ break; @@ -3064,6 +3188,15 @@ /* the outfile line was added above */ out_printf(out, "#undef PARENT_HANDLER\n"); break; + case CONSTRUCTOR_METHOD: + case DISPOSE_METHOD: + case FINALIZE_METHOD: + if(m->line_no > 0) + out_addline_infile(out, m->line_no); + print_method(out, "static ", "\n", "", " ", "", "\n", + m, FALSE, FALSE, TRUE, FALSE, FALSE); + print_method_body(m, TRUE, TRUE); + /* the outfile line was added above */ default: break; } @@ -3633,6 +3766,9 @@ funcbase); } =20 + if (need_constructor) + add_constructor (c); + if (need_dispose) add_dispose (c); =20 @@ -4441,15 +4577,24 @@ =20 make_bases (); make_inits ((Class *)class); - if(unreftors > 0) { + + find_constructor ((Class *)class); + if (user_constructor !=3D NULL) + need_constructor =3D TRUE; + + find_dispose ((Class *)class); + if (unreftors > 0 || + dispose_handler !=3D NULL || + user_dispose_method !=3D NULL) need_dispose =3D TRUE; - find_dispose ((Class *)class); - } + + find_finalize ((Class *)class); if (destructors > 0 || - privates > 0) { + privates > 0 || + user_finalize_method !=3D NULL) { need_finalize =3D TRUE; - find_finalize ((Class *)class); } + check_bad_symbols ((Class *)class); check_duplicate_symbols ((Class *)class); check_duplicate_overrides ((Class *)class); --- src/parse.y.orig 2007-03-09 18:46:14.000000000 +0100 +++ src/parse.y 2008-01-29 01:25:46.000000000 +0100 @@ -146,7 +146,7 @@ =20 static void push_function (int scope, int method, char *oid, char *id, - GString *cbuf, int line_no, int ccode_line, + GString *attr, GString *cbuf, int line_no, int ccode_line, gboolean vararg, GList *flags) { Node *node; @@ -155,7 +155,11 @@ =20 g_assert(scope !=3D CLASS_SCOPE); =20 - if(method =3D=3D INIT_METHOD || method =3D=3D CLASS_INIT_METHOD) { + if(method =3D=3D INIT_METHOD + || method =3D=3D CLASS_INIT_METHOD + || method =3D=3D CONSTRUCTOR_METHOD + || method =3D=3D DISPOSE_METHOD + || method =3D=3D FINALIZE_METHOD) { type =3D (Type *)node_new (TYPE_NODE, "name", "void", NULL); @@ -207,6 +211,7 @@ "args:steal", funcargs, "onerror:steal", onerror, "defreturn:steal", defreturn, + "attr:steal", attr ? attr->str : NULL, "cbuf:steal", c_cbuf, "line_no", line_no, "ccode_line", ccode_line, @@ -216,6 +221,8 @@ =20 last_added_method =3D (Method *)node; =20 + if(attr) + g_string_free(attr, FALSE); if(cbuf) g_string_free(cbuf, /*only free segment if we haven't passed it @@ -405,7 +412,7 @@ push_funcarg ("self", FALSE); =09 push_function (PUBLIC_SCOPE, REGULAR_METHOD, NULL, - get_id, get_cbuf, get_lineno, + get_id, NULL, get_cbuf, get_lineno, lineno, FALSE, NULL); } =09 @@ -439,7 +446,7 @@ =09 typestack =3D g_list_prepend (typestack, node2); push_function (PUBLIC_SCOPE, REGULAR_METHOD, NULL, - set_id, set_cbuf, set_lineno, + set_id, NULL, set_cbuf, set_lineno, lineno, FALSE, NULL); } =20 @@ -677,7 +684,7 @@ %token CONST VOID STRUCT UNION ENUM THREEDOTS %token SIGNED UNSIGNED LONG SHORT INT FLOAT DOUBLE CHAR =20 -%token <id> TOKEN NUMBER TYPETOKEN ARRAY_DIM SINGLE_CHAR +%token <id> TOKEN NUMBER TYPETOKEN ARRAY_DIM_OR_ATTR BITFIELD SINGLE_CHAR %token <cbuf> CCODE HTCODE PHCODE HCODE ACODE ATCODE STRING %token <line> PUBLIC PRIVATE PROTECTED CLASSWIDE PROPERTY ARGUMENT %token <line> VIRTUAL SIGNAL OVERRIDE @@ -982,7 +989,7 @@ variable: scope type TOKEN varoptions ';' { push_variable($<id>3, the_scope,$<line>1, NULL); } - | scope type TOKEN ARRAY_DIM varoptions ';' { + | scope type TOKEN array_dim varoptions ';' { push_variable($<id>3, the_scope, $<line>1, $<id>4); } ; @@ -1678,9 +1685,25 @@ YYERROR; } push_function(the_scope, $<sigtype>3,NULL, - $<id>5, $<cbuf>10,$<line>1, + $<id>5, NULL, $<cbuf>10,$<line>1, ccode_line, vararg, $<list>2); } + | attrs SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals c= odenocode { + if(!has_self) { + yyerror(_("signal without 'self' as " + "first parameter")); + free_all_global_state(); + YYERROR; + } + if(the_scope =3D=3D CLASS_SCOPE) { + yyerror(_("a method cannot be of class scope")); + free_all_global_state(); + YYERROR; + } + push_function(the_scope, $<sigtype>4,NULL, + $<id>6, $<cbuf>1, $<cbuf>11,$<line>2, + ccode_line, vararg, $<list>3); + } | scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' returnvals= codenocode { if(!has_self) { yyerror(_("signal without 'self' as " @@ -1694,9 +1717,25 @@ YYERROR; } push_function(the_scope, $<sigtype>4, NULL, - $<id>6, $<cbuf>11, $<line>2, + $<id>6, NULL, $<cbuf>11, $<line>2, ccode_line, vararg, $<list>3); } + | attrs scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' retu= rnvals codenocode { + if(!has_self) { + yyerror(_("signal without 'self' as " + "first parameter")); + free_all_global_state(); + YYERROR; + } + if(the_scope =3D=3D CLASS_SCOPE) { + yyerror(_("a method cannot be of class scope")); + free_all_global_state(); + YYERROR; + } + push_function(the_scope, $<sigtype>5, NULL, + $<id>7, $<cbuf>1, $<cbuf>12, $<line>3, + ccode_line, vararg, $<list>4); + } | VIRTUAL scope type TOKEN '(' funcargs ')' returnvals codenocode { if(!has_self) { yyerror(_("virtual method without 'self' as " @@ -1710,7 +1749,23 @@ YYERROR; } push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>4, - $<cbuf>9, $<line>1, + NULL, $<cbuf>9, $<line>1, + ccode_line, vararg, NULL); + } + | attrs VIRTUAL scope type TOKEN '(' funcargs ')' returnvals codenocode { + if(!has_self) { + yyerror(_("virtual method without 'self' as " + "first parameter")); + free_all_global_state(); + YYERROR; + } + if(the_scope =3D=3D CLASS_SCOPE) { + yyerror(_("a method cannot be of class scope")); + free_all_global_state(); + YYERROR; + } + push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>5, + $<cbuf>1, $<cbuf>10, $<line>2, ccode_line, vararg, NULL); } | scope VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode { @@ -1726,7 +1781,23 @@ YYERROR; } push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>4, - $<cbuf>9, $<line>2, + NULL, $<cbuf>9, $<line>2, + ccode_line, vararg, NULL); + } + | attrs scope VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode { + if(!has_self) { + yyerror(_("virtual method without 'self' as " + "first parameter")); + free_all_global_state(); + YYERROR; + } + if(the_scope =3D=3D CLASS_SCOPE) { + yyerror(_("a method cannot be of class scope")); + free_all_global_state(); + YYERROR; + } + push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>5, + $<cbuf>1, $<cbuf>10, $<line>3, ccode_line, vararg, NULL); } | VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode { @@ -1737,12 +1808,23 @@ YYERROR; } push_function(PUBLIC_SCOPE, VIRTUAL_METHOD, NULL, - $<id>3, $<cbuf>8, $<line>1, + $<id>3, NULL, $<cbuf>8, $<line>1, + ccode_line, vararg, NULL); + } + | attrs VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode { + if(!has_self) { + yyerror(_("virtual method without 'self' as " + "first parameter")); + free_all_global_state(); + YYERROR; + } + push_function(PUBLIC_SCOPE, VIRTUAL_METHOD, NULL, + $<id>4, $<cbuf>1, $<cbuf>9, $<line>2, ccode_line, vararg, NULL); } | OVERRIDE '(' TYPETOKEN ')' type TOKEN '(' funcargs ')' returnvals coden= ocode { push_function(NO_SCOPE, OVERRIDE_METHOD, $<id>3, - $<id>6, $<cbuf>11, + $<id>6, NULL, $<cbuf>11, $<line>1, ccode_line, vararg, NULL); } @@ -1753,32 +1835,74 @@ YYERROR; } push_function(the_scope, REGULAR_METHOD, NULL, $<id>3, - $<cbuf>8, $<line>1, ccode_line, + NULL, $<cbuf>8, $<line>1, ccode_line, + vararg, NULL); + } + | attrs scope type TOKEN '(' funcargs ')' returnvals codenocode { + if(the_scope =3D=3D CLASS_SCOPE) { + yyerror(_("a method cannot be of class scope")); + free_all_global_state(); + YYERROR; + } + push_function(the_scope, REGULAR_METHOD, NULL, $<id>4, + $<cbuf>1, $<cbuf>9, $<line>2, ccode_line, vararg, NULL); } | TOKEN '(' TOKEN ')' codenocode { if(strcmp($<id>1, "init")=3D=3D0) { push_init_arg($<id>3,FALSE); push_function(NO_SCOPE, INIT_METHOD, NULL, - $<id>1, $<cbuf>5, $<line>2, + $<id>1, NULL, $<cbuf>5, $<line>2, ccode_line, FALSE, NULL); } else if(strcmp($<id>1, "class_init")=3D=3D0) { push_init_arg($<id>3,TRUE); push_function(NO_SCOPE, CLASS_INIT_METHOD, NULL, - $<id>1, $<cbuf>5, $<line>2, + $<id>1, NULL, $<cbuf>5, $<line>2, + ccode_line, FALSE, NULL); + } else if(strcmp($<id>1, "constructor")=3D=3D0) { + push_init_arg($<id>3, FALSE); + push_function(NO_SCOPE, CONSTRUCTOR_METHOD, NULL, + $<id>1, NULL, $<cbuf>5, $<line>2, + ccode_line, FALSE, NULL); + } else if(strcmp($<id>1, "dispose")=3D=3D0) { + push_init_arg($<id>3, FALSE); + push_function(NO_SCOPE, DISPOSE_METHOD, NULL, + $<id>1, NULL, $<cbuf>5, $<line>2, + ccode_line, FALSE, NULL); + } else if(strcmp($<id>1, "finalize")=3D=3D0) { + push_init_arg($<id>3, FALSE); + push_function(NO_SCOPE, FINALIZE_METHOD, NULL, + $<id>1, NULL, $<cbuf>5, $<line>2, ccode_line, FALSE, NULL); } else { g_free($<id>1); g_free($<id>3); g_string_free($<cbuf>5,TRUE); yyerror(_("parse error " - "(untyped blocks must be init or " - "class_init)")); + "(untyped blocks must be init, " + "class_init, constructor, dispose " + "or finalize)")); YYERROR; } } ; =20 +attrs: + '[' CCODE { + $<cbuf>$ =3D $<cbuf>2; + } + | ARRAY_DIM_OR_ATTR { + int len =3D strlen($<id>1); + + g_assert($<id>1[0] =3D=3D '['); + g_assert(len >=3D 2 && $<id>1[len - 1] =3D=3D ']'); + + /* strip the brackets */ + $<cbuf>$ =3D g_string_new_len($<id>1 + 1, len - 2); + g_free($<id>1); + } + ; + returnvals: TOKEN retcode { g_free(onerror); onerror =3D NULL; g_free(defreturn); defreturn =3D NULL; @@ -1900,7 +2024,7 @@ arg: type TOKEN { push_funcarg($<id>2,NULL); } - | type TOKEN ARRAY_DIM { + | type TOKEN array_dim { push_funcarg($<id>2,$<id>3); } | type TOKEN '(' TOKEN checklist ')' { @@ -1911,7 +2035,7 @@ g_free($<id>4); push_funcarg($<id>2,NULL); } - | type TOKEN ARRAY_DIM '(' TOKEN checklist ')' { + | type TOKEN array_dim '(' TOKEN checklist ')' { if(strcmp($<id>5,"check")!=3D0) { yyerror(_("parse error")); YYERROR; @@ -2105,5 +2229,10 @@ | SINGLE_CHAR { $<id>$ =3D $<id>1; } | TOKEN { $<id>$ =3D $<id>1; } ; + +array_dim: + ARRAY_DIM_OR_ATTR + | BITFIELD + ; =09 %% --- src/treefuncs.def.orig 2007-03-09 18:46:14.000000000 +0100 +++ src/treefuncs.def 2008-01-29 01:25:46.000000000 +0100 @@ -40,6 +40,9 @@ REGULAR_METHOD, INIT_METHOD, CLASS_INIT_METHOD, + CONSTRUCTOR_METHOD, + DISPOSE_METHOD, + FINALIZE_METHOD, VIRTUAL_METHOD, SIGNAL_LAST_METHOD, SIGNAL_FIRST_METHOD, @@ -126,6 +129,7 @@ NODELIST args STRING onerror STRING defreturn + STRING attr STRING cbuf INT line_no INT ccode_line --Multipart=_Tue__29_Jan_2008_01_39_26_+0100_Em=asTXAOQy259Ny-- --Signature=_Tue__29_Jan_2008_01_39_26_+0100_wxW+IoBpsfHR4Hxx Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFHnnW+yzD7UaO4AGoRAusbAJ9huIrK/KWYEGmz+Ab+vvxJ1kIR7gCeKFcP GTA7yzBFKgSDqdLwrVvMmus= =aXrY -----END PGP SIGNATURE----- --Signature=_Tue__29_Jan_2008_01_39_26_+0100_wxW+IoBpsfHR4Hxx-- [email protected] Content-Type: text/plain; charset=us-ascii; name="footer.txt" Content-Disposition: inline Content-Transfer-Encoding: 8bit -- to unsubscribe: send mail to [email protected] with "unsubscribe gob-list" in the subject [email protected]