Message ID | 20100908134658.GA27775@hector.lesours |
---|---|
State | New |
Headers | show |
+/* Our ource directory and its length. */ Source @@ -249,7 +246,7 @@ static lang_bitmap get_lang_bitmap (const char *gtfile) { - if (gtfile == this_file) + if (gtfile == this_file || gtfile == system_h_file) /* Things defined in this file are universal. */ return (((lang_bitmap)1) << num_lang_dirs) - 1; else Can you explain this change? It looks sensible, but looks sort of unrelated to the rest of the patch. Was it a real bug before? Also, please add a comment, probably not here but next to some gtfile definition, why comparing const char * for pointer equality instead of using strcmp is OK. + /* In plugin mode we require some input files. */ + int i = 0; + if (optind >= argc) + fatal("no source files given in plugin mode"); + nb_plugin_files = argc - optind; + for (i = 0; i < (int) nb_plugin_files; i++) Just like the last time, I still don't get it. The usage help says: + printf ("\t -P | --plugin <output-file> \t# Generate for a plugin.\n"); And this code suggests -P <output-file> <input-file> <input-file> ... I think the usage help must mention the input files. /* These types are set up with #define or else outside of where - we can see them. */ + we can see them. We should initialize them before calling Suspicious formatting. +/* Structure representing an output file. */ +struct outf +{ + struct outf *next; + const char *name; + size_t buflength; + size_t bufused; + char *buf; +}; +typedef struct outf* outf_p; Formatting. Also I am not terribly happy about hiding a pointer in a typedef, but it's not prohibited I guess. +/* Variable used for reading and writing the state. */ +extern char *read_state_filename; +extern char *write_state_filename; Make these const (just like srcdir) 2010/9/8 Basile Starynkevitch <basile@starynkevitch.net>: > > Hello All, > > [join work by Basile Starynkevitch & Jeremie Salvucci] > > References: http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02058.html > http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02050.html > http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02051.html > http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00616.html > > The first piece [declprog] of our series of patches moves many private > definitions, types, functions from gengtype.c to gengtype.h & provide > a GNU friendly gengtype program invocation. Since a later patch of the > same serie implement the state persistency in a separate file > gengtype-state.c (see our future patch 6/N[wstate]) a lot of variables > & types which used to be internal to gengtype.c are now publicly > available in gengtype.h. > > > We did incorporate Paolo Bonzini's & Ralf Wildenhues' suggestions on > build/version.o in Makefile.in from > http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02114.html & > http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02050.html > > We did improve the help message as suggested by Laurynas Biveinis in > http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00207.html > > > Please notice an important point in this patch (and other patches of > this serie): we program defensively, since we feel that gengtype is > very difficult to understand. In particular, we added several > debugging tricks, notably the DBGPRINTF & DBGPRINT_COUNT_TYPE macros, > whose sole side-effect is to produce debugging output when gengtype is > given the --debug (or -D) program argument. This feature (only > available when ENABLE_CHECKING is configured) is deemed necessary > because gengtype code is really difficult to grasp and to debug. It > is complementary to the dump_everything & friends functions already > incorporated into gengtype and contributed by Laurynas Biveinis: > Laurynas dump feature is useful not only to debug and enhance gengtype > itself (a not trivial task, believe us!) but may also be useful by > gengtype users (e.g. plugins developers). In contrast, our DBGPRINTF > ... macros are mostly useful to debug & understand the processing of > gengtype itself. Of course, we could remove them, but we strongly > feel that they could be useful to some other gengtype hacker (the same > can be said of Laurynas dump facility). So to the attention of the > allmighty reviewers: please measure the pro & conses before asking us > to remove these DBGPRINTF macros. We really hope they will stay... > > ################################################################ > gcc/ChangeLog entry: > > 2010-09-08 Jeremie Salvucci <jeremie.salvucci@free.fr> > Basile Starynkevitch <basile@starynkevitch.net> > > * gengtype.c: Include getopt.h and version.h. > > (lang_bitmap, struct outf, outf_p) > (get_output_file_with_visibility, oprintf): Definitions moved to > gengtype.h > (output_files, header_file, srcdir, srcdir_len, this_file, do_dump): No > more static variables. > (do_debug): New. > (dbgprint_count_type_at): Added new function. > (gengtype_long_options): New. > (print_usage, print_version, parse_program_options): New. > (main): Call parse_program_options, and removed old option > handling code. Added some debug output. > > * gengtype.h: Updated copyright year. > (lang_bitmap, struct outf, outf_p, header_file, oprintf) > (get_output_file_with_visibility, srcdir, srcdir_len, do_dump): > Moved from gengtype.c to here. > (do_debug, read_state_filename, write_state_filename): New variables. > (DBGPRINTF, DBGPRINT_COUNT_TYPE): New macros. > > * Makefile.in: > (REVISION): Always defined. > (version.o): Removed ifdef REVISION_c. > (s-gtype): Pass arguments to build/gengtype program. > (build/version.o): Added building rule. > (build/gengtype$(build_exeext)): Added build/version.o. > ################################################################ > > Attached file: gengtype_patch_1_of_N__declprog-trunkrev-163987.diff > the diff file against trunk rev 163987. > > Ok for trunk? > > Regards. > -- > Basile STARYNKEVITCH http://starynkevitch.net/Basile/ > email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359 > 8, rue de la Faiencerie, 92340 Bourg La Reine, France > *** opinions {are only mines, sont seulement les miennes} *** >
On Thu, 9 Sep 2010 05:52:24 +0300 Laurynas Biveinis <laurynas.biveinis@gmail.com> wrote: > +/* Our ource directory and its length. */ > > Source > > @@ -249,7 +246,7 @@ static lang_bitmap > get_lang_bitmap (const char *gtfile) > { > > - if (gtfile == this_file) > + if (gtfile == this_file || gtfile == system_h_file) > /* Things defined in this file are universal. */ > return (((lang_bitmap)1) << num_lang_dirs) - 1; > else > > Can you explain this change? It looks sensible, but looks sort of > unrelated to the rest of the patch. Was it a real bug before? We did introduce the system_h_file. It could happen that get_lang_bitmap is never called on it, but if it where called, it could perhaps SEGV without the gtfile == system_h_file test, since system_h_file is like this_file, a const. This brings a question to the reviewer: I have the intuitive feeling that the gtfile == system_h_file is missing, but I cannot prove that. And the next patch will replace all the messy input file code with something less ugly, so this change is a very temporary kludge. Should I take days to try to understand why the current gengtype is working (I believe it is mostly chance). I'm not sure to have time for that, given that the next patch which is essentially http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02063.html rephrased a little bit, will remove that mess. And as you probably know, this patch piece is a very temporary fix. The next patch [not yet sent in the completed form, but essentially same as http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02063.html rephrased a little bit) is adding a real input_file structure, which removes all those nasty byte & bits manipulation, and the insane hypothesis that every file path have four bytes before it for its lang_bitmap. My feeling is that this hypothesis is already violated by "system.h" and that gengtype happens to work just by chance (it did already happen for http://gcc.gnu.org/ml/gcc-patches/2010-08/msg01992.html which we did commit later after typo corrections). But I don't want to spend days to investigate that. The next patch is clearing this mess thru a real input_file structure. > > Also, please add a comment, probably not here but next to some gtfile > definition, why comparing const char * for pointer equality instead of > using strcmp is OK. I believe there is such a comment somewhere in the old trunk gengtype. But the input files as strings are disappearing in the next patch. > > + /* In plugin mode we require some input files. */ > + int i = 0; > + if (optind >= argc) > + fatal("no source files given in plugin mode"); > + nb_plugin_files = argc - optind; > + for (i = 0; i < (int) nb_plugin_files; i++) > > Just like the last time, I still don't get it. The usage help says: > > + printf ("\t -P | --plugin <output-file> \t# Generate for a plugin.\n"); > Oh, I understand what you mean. Our usage don't mention input files for plugins! Will fix that. > And this code suggests > -P <output-file> <input-file> <input-file> ... > > I think the usage help must mention the input files. > > /* These types are set up with #define or else outside of where > - we can see them. */ > + we can see them. We should initialize them before calling > > Suspicious formatting. > > +/* Structure representing an output file. */ > +struct outf > +{ > + struct outf *next; > + const char *name; > + size_t buflength; > + size_t bufused; > + char *buf; > +}; > +typedef struct outf* outf_p; > > Formatting. Also I am not terribly happy about hiding a pointer in a > typedef, but it's not prohibited I guess. I am not happy neither, but the current trunk's gengtype already had the "typedef struct outf* outf_p;" definition. I agree with you, it is disgusting. If I was not scared by reviewers availability, I would on the contrary use "typedef struct output_file_st output_file;" and use "output_file*" everywhere instead of "outf_p". However, doing that would increase significantly the length of the patch, and I am very scared of discouraging potential reviewers. If some reviewer (i.e. a person invested with the power to OK that patch) would say to me that it is welcome, I would be very happy to make the change. But I am scared of making patches bigger than what a reviewer can digest, and I do confess that reading gengtype code is not fun at all. Even with our patches, gengtype remains ugly. I think it is better if I send the next patches as soon as possible. I am not forgetting or ignoring your feedback, but I believe that to keep reviewer's attention I should focus on sending this complete round of patch in totality first. After having sent the complete serie of "completed!" patches, I will remake a third round. I still don't understand who has a reviewer hat, and I still don't understand if our patches have any chance to go into trunk before end of stage 1 which is scheduled for october 27th. And while I do understand the need to commit code of high quality, for gengtype specifically I believe the code was so badly written that reviewers should be a little less harsh with us. We do know that our code is not perfect, but gengtype is so awefully coded that our patch serie is still a minor improvement. To say it frankly, the code existing in trunk's gengtype is so aweful that it should never had been accepted in the first place. Apparently, at that time (2002? perhaps) the philosophy was: if it happens to work, commit it. But today the requirements are much bigger! However, I have not enough time to understand why the current trunk gengtype is working. In my view, it is by chance (there are probably several bugs like http://gcc.gnu.org/ml/gcc-patches/2010-08/msg01992.html inside it). And I certainly don't have time to correct every such bug inside. Regards.
2010/9/9 Basile Starynkevitch <basile@starynkevitch.net>: > This brings a question to the reviewer: I have the intuitive feeling > that the gtfile == system_h_file is missing, but I cannot prove that. > And the next patch will replace all the messy input file code with > something less ugly, so this change is a very temporary kludge. In that case might as well just drop this change, since your patches will probably go into the trunk all at once. >> Also, please add a comment, probably not here but next to some gtfile >> definition, why comparing const char * for pointer equality instead of >> using strcmp is OK. > > I believe there is such a comment somewhere in the old trunk gengtype. > But the input files as strings are disappearing in the next patch. True. Please disregard my comment then. >> +typedef struct outf* outf_p; >> >> Formatting. Also I am not terribly happy about hiding a pointer in a >> typedef, but it's not prohibited I guess. > > I am not happy neither, but the current trunk's gengtype already had > the "typedef struct outf* outf_p;" definition. I agree with you, it is > disgusting. > > If I was not scared by reviewers availability, I would on the contrary > use "typedef struct output_file_st output_file;" > and use "output_file*" everywhere instead of "outf_p". > However, doing that would increase significantly the length of the > patch, and I am very scared of discouraging potential reviewers. If > some reviewer (i.e. a person invested with the power to OK that patch) > would say to me that it is welcome, I would be very happy to make the > change. But I am scared of making patches bigger than what a reviewer > can digest, and I do confess that reading gengtype code is not fun at > all. Even with our patches, gengtype remains ugly. Follow-up patches are welcome, and they don't scare reviewers away ;) > And while I do understand the need to commit code of high quality, for > gengtype specifically I believe the code was so badly written that > reviewers should be a little less harsh with us. I don't understand. Is anyone harsh with you? For the record, I am not asking to rewrite gengtype to improve its design. If my comments happen to touch things that are simply unchanged by your patches, then they are strictly optional (and perhaps best done as followup patches). And I don't think that asking for proper code formatting is harsh in any way ;) > We do know that our > code is not perfect, but gengtype is so awefully coded that our patch > serie is still a minor improvement. I completely agree. > To say it frankly, the code existing in trunk's gengtype is so aweful > that it should never had been accepted in the first place. Apparently, > at that time (2002? perhaps) the philosophy was: if it happens to work, > commit it. But today the requirements are much bigger! I think it went in without reviews, which, as you are experiencing, haunts us 8 years later: http://gcc.gnu.org/ml/gcc-patches/2002-06/msg00328.html http://gcc.gnu.org/ml/gcc-patches/2002-06/msg00331.html
On Thu, 9 Sep 2010 09:35:55 +0300 Laurynas Biveinis <laurynas.biveinis@gmail.com> wrote, citing me Basile: [....] > > If I was not scared by reviewers availability, I would on the contrary > > use "typedef struct output_file_st output_file;" > > and use "output_file*" everywhere instead of "outf_p". > > However, doing that would increase significantly the length of the > > patch, and I am very scared of discouraging potential reviewers. If > > some reviewer (i.e. a person invested with the power to OK that patch) > > would say to me that it is welcome, I would be very happy to make the > > change. But I am scared of making patches bigger than what a reviewer > > can digest, and I do confess that reading gengtype code is not fun at > > all. Even with our patches, gengtype remains ugly. > > Follow-up patches are welcome, and they don't scare reviewers away ;) What exactly do you mean by "follow-up patches" in this particular context? I have several meanings in mind, and I cannot chose the best one. > > > And while I do understand the need to commit code of high quality, for > > gengtype specifically I believe the code was so badly written that > > reviewers should be a little less harsh with us. > > I don't understand. Is anyone harsh with you? For the record, I am not > asking to rewrite gengtype to improve its design. If my comments > happen to touch things that are simply unchanged by your patches, then > they are strictly optional (and perhaps best done as followup > patches). And I don't think that asking for proper code formatting is > harsh in any way ;) Maybe "harsh" was a wrong word. I probably just meant "strong" or "severe" or "stern". English is not my native language, and I have to look into dictionnaries (and I am not doing often enough that effort). In particular, I find strong the requirement of explaining any temporary fix which will be dismantled by the next patch. And such fixes are implied by the requirement of making gengtype still work as before at every piece of the patch set. Our work is seperated in pieces of patch for convenience of reviewers. It would be much much easier to us to be permitted to send a single big patch all at once, with a long message explaining every part of it. But apparently the GCC community or reviewers don't want that (even if it seems to have happened in the past). The requirement to have gengtype working at every patch piece is in retrospect a very strong one even if I do understand it. The requirement to explain every kludge needed for that is unrealistic. It requires us to understand why gengtype is working currently (I am not able to do that), and the only good answer today is "by accident". Please accept my apologies for using the wrong word "harsh". Proper code formatting is a must, but I cannot understand how to achieve that simply & reliably. So far, I just manually read several times the code before sending, but my brain is too familiar with my own patch. I would be very tempted to run "indent -gnu gengtype.c" but I feel it will add a lot of noise in the patch. Or should I run it? Cheers.
2010/9/9 Basile Starynkevitch <basile@starynkevitch.net>: > On Thu, 9 Sep 2010 09:35:55 +0300 > Laurynas Biveinis <laurynas.biveinis@gmail.com> wrote, citing me Basile: > > [....] > >> > If I was not scared by reviewers availability, I would on the contrary >> > use "typedef struct output_file_st output_file;" >> > and use "output_file*" everywhere instead of "outf_p". >> > However, doing that would increase significantly the length of the >> > patch, and I am very scared of discouraging potential reviewers. If >> > some reviewer (i.e. a person invested with the power to OK that patch) >> > would say to me that it is welcome, I would be very happy to make the >> > change. But I am scared of making patches bigger than what a reviewer >> > can digest, and I do confess that reading gengtype code is not fun at >> > all. Even with our patches, gengtype remains ugly. >> >> Follow-up patches are welcome, and they don't scare reviewers away ;) > > What exactly do you mean by "follow-up patches" in this particular > context? I have several meanings in mind, and I cannot chose the best > one. A separate, self-contained after you get your main batch accepted, patch which would just change typedef struct foo * foo_p; to typedef struct foo foo; and change all usages accordingly. > In particular, I find strong the requirement of explaining > any temporary fix which will be dismantled by the next patch. And such > fixes are implied by the requirement of making gengtype still work as > before at every piece of the patch set. Oh. I might be wrong, but I don't think that's necessary. You have a set of patches which are interdependent. I think it is fine for an arbitrary subset of these patches to break something as long as the end result is OK. Can you point to where you were told to make sure that gengtype works as before _at every step_? > Proper code formatting is a must, but I cannot understand how to > achieve that simply & reliably. By using a tool that's configured to correctly format what you type. http://gcc.gnu.org/wiki/FormattingCodeForGCC > I would be very tempted to run "indent -gnu gengtype.c" but I > feel it will add a lot of noise in the patch. Or should I run it? Please don't, that only makes reviewer's life harder and breaks svn blame.
On Thu, Sep 09, 2010 at 10:23:15AM +0300, Laurynas Biveinis wrote: > 2010/9/9 Basile Starynkevitch <basile@starynkevitch.net>: > > On Thu, 9 Sep 2010 09:35:55 +0300 > > > In particular, I find strong the requirement of explaining > > any temporary fix which will be dismantled by the next patch. And such > > fixes are implied by the requirement of making gengtype still work as > > before at every piece of the patch set. > > Oh. I might be wrong, but I don't think that's necessary. You have a > set of patches which are interdependent. I think it is fine for an > arbitrary subset of these patches to break something as long as the > end result is OK. Can you point to where you were told to make sure > that gengtype works as before _at every step_? In http://gcc.gnu.org/ml/gcc/2010-08/msg00353.html Ian Taylor wrote in a reply to my questions >> An ideal sequence of patches is a series of patches which may be applied >> in order. At each stage the tree should be buildable. The patches >> don't have to be independent--they can be applied in a specific >> order--but they should each work. I understood the above paragraph from Ian as requirement that gengtype should always work at every stage, i.e. _at every step_ to quote Laurynas. Maybe I misunderstood, or took as a requirement what is just an ideal wish, that is something which is not realistically achievable but just wanted in a Platonic world which does not exist in GCC. And believe me, gengtype, even with our patch set, is *very far* from being ideal. It will remain crappy forever because garbage collection is a *global* property of a program, and there is still no consensus within the GCC community about it; my "purist" view is that the GCC community should require every dynamically allocated data to be garbage collected with almost no exceptions, and then implement the tools [GC support à la Ggc but better, code generators much better than gengtype] to make that happen. But I do know that most people disagree with my disruptive & extreme position. Notice that transition to C++ could help and be an incentive for better garbage collection (C++ permit virtual functions as marking routines and could wrap nicely local GC-ed pointers). But in general, as long as there is no strong consensus on any *global* property of GCC, we won't be able to implement it cleanly and robustly. This is true of every *global* property or feature of GCC, e.g. memory management, organization of passes, code formatting style, or GCC documentation. Cheers.
2010/9/9 Basile Starynkevitch <basile@starynkevitch.net>: >> Oh. I might be wrong, but I don't think that's necessary. You have a >> set of patches which are interdependent. I think it is fine for an >> arbitrary subset of these patches to break something as long as the >> end result is OK. Can you point to where you were told to make sure >> that gengtype works as before _at every step_? > > In http://gcc.gnu.org/ml/gcc/2010-08/msg00353.html Ian Taylor wrote in > a reply to my questions > >>> An ideal sequence of patches is a series of patches which may be applied >>> in order. At each stage the tree should be buildable. The patches >>> don't have to be independent--they can be applied in a specific >>> order--but they should each work. I think that you shouldn't be required support such things as gengtype working perfectly after each step, if this means that you have to clutter your patches with code specifically for that and which will never ever be exercised by gengtype in the trunk.
On 09/09/2010 12:08 PM, Laurynas Biveinis wrote: > 2010/9/9 Basile Starynkevitch <basile@starynkevitch.net>: >> In http://gcc.gnu.org/ml/gcc/2010-08/msg00353.html Ian Taylor wrote in >> a reply to my questions >> >>>> An ideal sequence of patches is a series of patches which may be applied >>>> in order. At each stage the tree should be buildable. The patches >>>> don't have to be independent--they can be applied in a specific >>>> order--but they should each work. > > I think that you shouldn't be required support such things as gengtype > working perfectly after each step, if this means that you have to > clutter your patches with code specifically for that and which will > never ever be exercised by gengtype in the trunk. The point is that breaking up the patches is not just for review, it's also for checking in smaller pieces. That allows each piece to be tested, and it helps identify problems more easily later, but for that to work every piece must result in a working compiler. Bernd
> * Makefile.in: > (REVISION): Always defined. > (version.o): Removed ifdef REVISION_c. > (s-gtype): Pass arguments to build/gengtype program. > (build/version.o): Added building rule. > (build/gengtype$(build_exeext)): Added build/version.o. Build parts are ok, thanks! Paolo
On 09/09/2010 08:07 AM, Basile Starynkevitch wrote:
> I still don't understand who has a reviewer hat
Everybody can informally review patches, including you.
Instead, what MAINTAINERS tell you is who approve patches; "maintainers"
do not need external reviews, "reviewers" do. Maybe "committers" and
"maintainers" could be a better choice of words, but that's too late now
to change it.
There are 2*2 possible scenarios which involve reviews from people not
in MAINTAINERS:
1) Ralf reviews the patch and finds it is okay. After I read his
review, I still have to approve it explicitly if I agree, or reject it
if I disagree.
2) I approve the patch, but Ralf comes and finds something I missed.
It's usually good manners on your part to avoid committing the patch
until I come back and resolve the problem (usually by rejecting the
patch :).
3) Laurynas comes first and he points out problems in your patch. The
actual maintainers/reviewers usually will not reject the patch
explicitly if they agree with him, but you should assume they do. Maybe
they can say "Ok with the changes suggested by Laurynas", in which case
you can fix the changes and commit the patch.
4) Laurynas points out problems in your patch, the actual
maintainers/reviewers disagree. They start a discussion and you'll
notice it.
To some up, usually you should pay more attention to bad news than to
good news if you want your patches to go in. :)
Also, for patch series as big as this one you should really, really
learn quilt or git. (I wrote my own simplified version of quilt, but I
was a student when I did...).
Paolo
On Thu, Sep 09, 2010 at 03:02:10PM +0200, Paolo Bonzini wrote: > On 09/09/2010 08:07 AM, Basile Starynkevitch wrote: > >I still don't understand who has a reviewer hat > > Everybody can informally review patches, including you. > > Instead, what MAINTAINERS tell you is who approve patches; > "maintainers" do not need external reviews, "reviewers" do. Maybe > "committers" and "maintainers" could be a better choice of words, > but that's too late now to change it. > > There are 2*2 possible scenarios which involve reviews from people > not in MAINTAINERS: Thanks for the explanation! [....] > > > To some up, usually you should pay more attention to bad news than > to good news if you want your patches to go in. :) I try hard to follow the bad news. > > Also, for patch series as big as this one you should really, really > learn quilt or git. (I wrote my own simplified version of quilt, > but I was a student when I did...). I will continue sending the patch series "completed!" but I am not at all ignoring the comments gotten so far. after I end sending this "completed!" series, I will send again a "third round" serie of patches, taking into account every comment recieved so far. Regarding formatting & indentation issues, Jeremie Salvucci, when he typed code, had a non GNU-conformant .emacs (while I Basile hopefully do have a GNU conformant .emacs file). This explains the many indentation issues. But I am the only one to be blamed. Jeremie was my intern, and I made the mistake to not noticing that his .emacs was not conformant to GCC rules, and to not correcting Jeremie's coding habits while he was typing with me. So please blame me Basile, not him Jeremie! Regarding my next serie of patches - the incoming third round - I would like very much to get a concrete advice regarding quilt use. Paolo, what concrete procedure do you suggest? I was thinking of starting from a more recent trunk, apply each patch I am sending in this second round "complete!" serie, re-reading them manually, re-indenting with Emacs with correct setting, and of course re-reading all the comments we got so far. But I miss how to concretely use quilt in that case. Or do you think it is too late to use quilt? Cheers.
On 09/09/2010 03:28 PM, Basile Starynkevitch wrote: > Regarding my next serie of patches - the incoming third round - I > would like very much to get a concrete advice regarding quilt > use. Paolo, what concrete procedure do you suggest? I was thinking of > starting from a more recent trunk, apply each patch I am sending in > this second round "complete!" serie, re-reading them manually, > re-indenting with Emacs with correct setting, and of course re-reading > all the comments we got so far. But I miss how to concretely use quilt > in that case. Or do you think it is too late to use quilt? No idea exactly of how to use quilt because I don't use it, but it looks like the right plan. The main problem is that after you fix indentation for patch 1, parts of patch 2 will not apply. So you need some patience, but you don't lack it. Emacs diff-mode helps a lot in this respect. Paolo
On Thu, 9 Sep 2010, Paolo Bonzini wrote: > Also, for patch series as big as this one you should really, really learn > quilt or git. (I wrote my own simplified version of quilt, but I was a > student when I did...). Or, for the future, submit minimal self-contained patches as you go along as far as possible rather than building up a huge change you then need to split up. My multilibs / option handling series has more than 40 patches so far (the exact number depending on how you count), submitted and reviewed one at a time rather than building up a branch and then trying to split it, no quilt, no git. Whenever in the course of a larger development you find yourself fixing an issue present on trunk, or cleaning up in a way also applicable to trunk, you should at least consider stopping making that change in the context of your larger development, preparing and submitting a trunk version of that fix instead, then merging trunk into the sources used for your larger development to get the fix into them.
On Thu, Sep 9, 2010 at 09:42, Joseph S. Myers <joseph@codesourcery.com> wrote: > Whenever in the course of a larger development you find yourself fixing an > issue present on trunk, or cleaning up in a way also applicable to trunk, > you should at least consider stopping making that change in the context of > your larger development, preparing and submitting a trunk version of that > fix instead, then merging trunk into the sources used for your larger > development to get the fix into them. Agreed. Even, if you are working on a long lived branch, take advantage of all the stage 1s to flush out all those dozen little cleanups that may have accumulated during the project. This makes your main contribution that much easier to separate from the fluff. Diego.
Index: gcc-gengtypeincr-trunk/gcc/gengtype.c =================================================================== --- gcc-gengtypeincr-trunk/gcc/gengtype.c (revision 163987) +++ gcc-gengtypeincr-trunk/gcc/gengtype.c (working copy) @@ -20,10 +20,12 @@ #include "bconfig.h" #include "system.h" -#include "gengtype.h" #include "errors.h" /* for fatal */ +#include "getopt.h" #include "double-int.h" +#include "version.h" /* for version_string & pkgversion_string */ #include "hashtab.h" +#include "gengtype.h" /* Data types, macros, etc. used only in this file. */ @@ -39,7 +41,6 @@ enum typekind { TYPE_PARAM_STRUCT }; -typedef unsigned lang_bitmap; /* A way to pass data through to the output end. */ struct options @@ -120,47 +121,42 @@ struct type || (x)->kind == TYPE_STRUCT \ || (x)->kind == TYPE_LANG_STRUCT) -/* Structure representing an output file. */ -struct outf -{ - struct outf *next; - const char *name; - size_t buflength; - size_t bufused; - char *buf; -}; -typedef struct outf * outf_p; -/* An output file, suitable for definitions, that can see declarations - made in INPUT_FILE and is linked into every language that uses - INPUT_FILE. May return NULL in plugin mode. */ -extern outf_p get_output_file_with_visibility - (const char *input_file); + const char *get_output_file_name (const char *); -/* Print, like fprintf, to O. No-op if O is NULL. */ -static void oprintf (outf_p o, const char *S, ...) - ATTRIBUTE_PRINTF_2; /* The list of output files. */ -static outf_p output_files; +outf_p output_files; +/* The output header file that is included into pretty much every + source file. */ +outf_p header_file; + + +/* The name of the file containing the list of input files. */ +static char* inputlist; + /* The plugin input files and their number; in that case only a single file is produced. */ static char** plugin_files; static size_t nb_plugin_files; -/* the generated plugin output name & file */ + +/* the generated plugin output file and name. */ static outf_p plugin_output; +static char* plugin_output_filename; -/* The output header file that is included into pretty much every - source file. */ -static outf_p header_file; +/* Our ource directory and its length. */ +const char *srcdir; +size_t srcdir_len; -/* Source directory. */ -static const char *srcdir; +/* Variables used for reading and writing the state! */ +char *read_state_filename; +char *write_state_filename; -/* Length of srcdir name. */ -static size_t srcdir_len = 0; +/* Variables to help debugging. */ +int do_dump; +int do_debug; static outf_p create_file (const char *, const char *); @@ -223,7 +219,8 @@ static size_t num_gt_files; /* A number of places use the name of this file for a location for things that we can't rely on the source to define. Make sure we can still use pointer comparison on filenames. */ -static const char this_file[] = __FILE__; +const char this_file[] = __FILE__; +const char system_h_file[] = "system.h"; /* Vector of per-language directories. */ static const char **lang_dir_names; @@ -249,7 +246,7 @@ static lang_bitmap get_lang_bitmap (const char *gtfile) { - if (gtfile == this_file) + if (gtfile == this_file || gtfile == system_h_file) /* Things defined in this file are universal. */ return (((lang_bitmap)1) << num_lang_dirs) - 1; else @@ -275,6 +272,66 @@ set_lang_bitmap (char *gtfile, lang_bitmap n) } } + +#if ENABLE_CHECKING +/* Utility debugging function, printing the various type counts within + a list of types. Called thru the DBGPRINT_COUNT_TYPE macro. */ +void dbgprint_count_type_at (const char*fil, int lin, const char*msg, type_p t) +{ + int nb_types=0, nb_scalar=0, nb_string=0; + int nb_struct=0, nb_union=0, nb_array=0, nb_pointer=0; + int nb_lang_struct=0, nb_param_struct=0; + type_p p=NULL; + for (p=t; p; p=p->next) + { + nb_types++; + switch (p->kind) { + case TYPE_SCALAR: + nb_scalar++; + break; + case TYPE_STRING: + nb_string++; + break; + case TYPE_STRUCT: + nb_struct++; + break; + case TYPE_UNION: + nb_union++; + break; + case TYPE_POINTER: + nb_pointer++; + break; + case TYPE_ARRAY: + nb_array++; + break; + case TYPE_LANG_STRUCT: + nb_lang_struct++; + break; + case TYPE_PARAM_STRUCT: + nb_param_struct++; + break; + default: + gcc_unreachable (); + } + } + fprintf (stderr, "\n" "%s:%d: %s: @@%%@@ %d types ::\n", + lbasename(fil), lin, msg, nb_types); + if (nb_scalar>0 || nb_string>0) + fprintf (stderr, "@@%%@@ %d scalars, %d strings\n", + nb_scalar, nb_string); + if (nb_struct>0 || nb_union>0) + fprintf (stderr, "@@%%@@ %d structs, %d unions\n", + nb_struct, nb_union); + if (nb_pointer>0 || nb_array>0) + fprintf (stderr, "@@%%@@ %d pointers, %d arrays\n", + nb_pointer, nb_array); + if (nb_lang_struct>0 || nb_param_struct>0) + fprintf (stderr, "@@%%@@ %d lang_structs, %d param_structs\n", + nb_lang_struct, nb_param_struct); + fprintf(stderr, "\n"); +} +#endif /*ENABLE_CHECKING*/ + /* Scan the input file, LIST, and determine how much space we need to store strings in. Also, count the number of language directories and files. The numbers returned are overestimates as they does not @@ -4209,64 +4266,159 @@ dump_everything (void) } -int -main (int argc, char **argv) + +/* Option specification for getopt_long. */ +static const struct option gengtype_long_options[] = { - size_t i; - static struct fileloc pos = { this_file, 0 }; - char* inputlist = 0; - int do_dump = 0; - outf_p output_header; - char* plugin_output_filename = NULL; - /* fatal uses this */ - progname = "gengtype"; + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { "dump", no_argument, NULL, 'd' }, + { "debug", no_argument, NULL, 'D' }, + { "plugin", required_argument, NULL, 'P' }, + { "srcdir", required_argument, NULL, 'S' }, + { "inputs", required_argument, NULL, 'I' }, + { "read-state", required_argument, NULL, 'r' }, + { "write-state", required_argument, NULL, 'w' }, + { NULL, no_argument, NULL, 0 }, +}; - if (argc >= 2 && !strcmp (argv[1], "-d")) + +static void +print_usage (void) +{ + printf ("Usage: %s\n", progname); + printf ("\t -h | --help \t# Give this help.\n"); + printf ("\t -D | --debug \t# Give lots of debug output to debug %s itself.\n", progname); + printf ("\t -V | --version \t# Give version information.\n"); + printf ("\t -d | --dump \t# Dump state for debugging.\n"); + printf ("\t -P | --plugin <output-file> \t# Generate for a plugin.\n"); + printf ("\t -S | --srcdir <GCC-directory> \t# Specify the GCC source directory.\n"); + printf ("\t -I | --inputs <input-list> \t# Specify the file with source files list.\n"); + printf ("\t -w | --write-state <state-file> \t# Write a state file (for plugin use).\n"); + printf ("\t -r | --read-state <state-file> \t# Read a state file.\n"); +} + +static void +print_version (void) +{ + printf ("%s %s%s\n", progname, pkgversion_string, version_string); + printf ("Report bugs: %s\n", bug_report_url); +} + +/* Parse the program options using getopt_long... */ +static void +parse_program_options (int argc, char**argv) +{ + int opt = -1; + while ((opt = getopt_long (argc, argv, "hVdP:S:I:w:r:D", + gengtype_long_options, NULL)) >= 0) { + switch (opt) + { + case 'h': /* --help */ + print_usage (); + break; + case 'V': /* --version */ + print_version (); + break; + case 'd': /* --dump */ do_dump = 1; - argv = &argv[1]; - argc--; + break; + case 'D': /* --debug */ + do_debug = 1; + break; + case 'P': /* --plugin */ + if (optarg) + plugin_output_filename = optarg; + else + fatal ("missing plugin output file name"); + break; + case 'S': /* --srcdir */ + if (optarg) + srcdir = optarg; + else + fatal ("missing source directory"); + srcdir_len = strlen (srcdir); + break; + case 'I': /* --inputs */ + if (optarg) + inputlist = optarg; + else + fatal ("missing input list"); + break; + case 'r': /* --read-state */ + if (optarg) + read_state_filename = optarg; + else + fatal ("missing read state file"); + DBGPRINTF ("read state %s\n", optarg); + break; + case 'w': /* --write-state */ + DBGPRINTF ("write state %s\n", optarg); + if (optarg) + write_state_filename = optarg; + else + fatal ("missing write state file"); + break; + default: + fprintf (stderr, "%s: unknown flag '%c'\n", progname, opt); + print_usage (); + fatal ("unexpected flag"); } - - if (argc >= 6 && !strcmp (argv[1], "-P")) + }; + if (plugin_output_filename) { - plugin_output_filename = argv[2]; - plugin_output = create_file ("GCC", plugin_output_filename); - srcdir = argv[3]; - inputlist = argv[4]; - nb_plugin_files = argc - 5; - plugin_files = XCNEWVEC (char *, nb_plugin_files); - for (i = 0; i < nb_plugin_files; i++) + /* In plugin mode we require some input files. */ + int i = 0; + if (optind >= argc) + fatal("no source files given in plugin mode"); + nb_plugin_files = argc - optind; + for (i = 0; i < (int) nb_plugin_files; i++) { - /* Place an all zero lang_bitmap before the plugin file - name. */ - char *name = argv[i + 5]; - int len = strlen(name) + 1 + sizeof (lang_bitmap); - plugin_files[i] = XCNEWVEC (char, len) + sizeof (lang_bitmap); - strcpy (plugin_files[i], name); + char *name = argv[i + optind]; + plugin_files[i] = name; } } - else if (argc == 3) - { - srcdir = argv[1]; - inputlist = argv[2]; - } - else - fatal ("usage: gengtype [-d] [-P pluginout.h] srcdir input-list " - "[file1 file2 ... fileN]"); +} - srcdir_len = strlen (srcdir); - read_input_list (inputlist); - if (hit_error) - return 1; +int +main (int argc, char **argv) +{ + size_t i; + static struct fileloc pos = { NULL, 0 }; + outf_p output_header; + + /* Mandatory common initializations. */ + progname = "gengtype"; /* For fatal and messages. */ + /* Set the scalar_is_char union number for predefined scalar types. */ + scalar_nonchar.u.scalar_is_char = FALSE; + scalar_char.u.scalar_is_char = TRUE; - scalar_char.u.scalar_is_char = true; - scalar_nonchar.u.scalar_is_char = false; - gen_rtx_next (); + parse_program_options (argc, argv); +#if ENABLE_CHECKING + if (do_debug) + { + time_t now; + time (&now); + DBGPRINTF ("gengtype started pid %d at %s", (int) getpid(), ctime(&now)); + } +#endif + + /*** Parse the input list and the input files. ***/ + DBGPRINTF ("inputlist %s", inputlist); + if (read_state_filename) + { + fatal ("read state %s not implemented yet", read_state_filename); + /* TODO: implement read state. */ + } + else if (inputlist) + { /* These types are set up with #define or else outside of where - we can see them. */ + we can see them. We should initialize them before calling + read_input_list. */ + pos.file = this_file; pos.line = __LINE__ + 1; do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++; do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++; @@ -4278,22 +4430,80 @@ dump_everything (void) do_scalar_typedef ("JCF_u2", &pos); pos.line++; do_scalar_typedef ("void", &pos); pos.line++; do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos); - - for (i = 0; i < num_gt_files; i++) + read_input_list (inputlist); + for (i = 0; i < num_gt_files; i++) { parse_file (gt_files[i]); + DBGPRINTF ("parsed file #%d %s", (int) i, gt_files[i]); + } + DBGPRINT_COUNT_TYPE ("structures after parsing", structures); + DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs); + } + else + fatal ("either an input list or a read state file should be given"); if (hit_error) return 1; + + if (plugin_output_filename) + { + size_t ix = 0; + /* In plugin mode, we should have read a state file, and have + given at least one plugin file. */ + if (!read_state_filename) + fatal ("No read state given in plugin mode for %s", plugin_output_filename); + + if (nb_plugin_files <= 0 || !plugin_files) + fatal ("No plugin files given in plugin mode for %s", plugin_output_filename); + + /* Parse our plugin files. */ + for (ix = 0; ix < nb_plugin_files; ix++) + parse_file (plugin_files[ix]); + + if (hit_error) + return 1; + + plugin_output = create_file ("GCC", plugin_output_filename); + DBGPRINTF ("created plugin_output %p named %s", + (void*) plugin_output, plugin_output->name); + } + + else + { /* No plugin files, we are in normal mode. */ + if (!srcdir) + fatal ("gengtype needs a source directory in normal mode"); + } + if (hit_error) + return 1; + + gen_rtx_next (); + + /* The call to set_gc_used may indirectly call find_param_structure + hence enlarge the param_structs list of types. So it should + happen before writing the state. */ set_gc_used (variables); + /* We should write the state here, but it is not yet implemented. */ + if (write_state_filename) + { + fatal ("write state %s in not yet implemented", write_state_filename); + /* TODO: implement write state */ + } + + open_base_files (); + write_enum_defn (structures, param_structs); write_typed_alloc_defns (structures, typedefs); output_header = plugin_output ? plugin_output : header_file; + DBGPRINT_COUNT_TYPE ("structures before write_types outputheader", structures); + DBGPRINT_COUNT_TYPE ("param_structs before write_types outputheader", param_structs); + write_types (output_header, structures, param_structs, &ggc_wtd); if (plugin_files == NULL) { + DBGPRINT_COUNT_TYPE ("structures before write_types headerfil", structures); + DBGPRINT_COUNT_TYPE ("param_structs before write_types headerfil", param_structs); write_types (header_file, structures, param_structs, &pch_wtd); write_local (header_file, structures, param_structs); } @@ -4305,12 +4515,7 @@ dump_everything (void) if (do_dump) dump_everything (); - if (plugin_files) - { - for (i = 0; i < nb_plugin_files; i++) - free (plugin_files[i] - sizeof (lang_bitmap)); - free (plugin_files); - } + /* don't bother about free-ing any input file, etc. */ if (hit_error) return 1; Index: gcc-gengtypeincr-trunk/gcc/gengtype.h =================================================================== --- gcc-gengtypeincr-trunk/gcc/gengtype.h (revision 163987) +++ gcc-gengtypeincr-trunk/gcc/gengtype.h (working copy) @@ -1,5 +1,6 @@ /* Process source files and output type information. - Copyright (C) 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2007, 2008, 2010 + Free Software Foundation, Inc. This file is part of GCC. @@ -20,6 +21,10 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_GENGTYPE_H #define GCC_GENGTYPE_H +/* Sets of accepted source languages like C, C++, Ada ... are + represented by a bitmap. */ +typedef unsigned lang_bitmap; + /* A file position, mostly for error messages. The FILE element may be compared using pointer equality. */ struct fileloc { @@ -37,6 +42,44 @@ typedef struct options *options_p; extern int lexer_toplevel_done; extern struct fileloc lexer_line; +/* Structure representing an output file. */ +struct outf +{ + struct outf *next; + const char *name; + size_t buflength; + size_t bufused; + char *buf; +}; +typedef struct outf* outf_p; + +/* The list of output files. */ +extern outf_p output_files; + +/* The output header file that is included into pretty much every + source file. */ +extern outf_p header_file; + +/* Print, like fprintf, to O. No-op if O is NULL. */ +void oprintf (outf_p o, const char *S, ...) + ATTRIBUTE_PRINTF_2; + +/* An output file, suitable for definitions, that can see declarations + made in INPUT_FILE and is linked into every language that uses + INPUT_FILE. May return NULL in plugin mode. */ +extern outf_p get_output_file_with_visibility + (const char *input_file); + +/* Source directory. */ +extern const char *srcdir; + +/* Length of srcdir name. */ +extern size_t srcdir_len; + +/* Variable used for reading and writing the state. */ +extern char *read_state_filename; +extern char *write_state_filename; + /* Print an error message. */ extern void error_at_line (const struct fileloc *pos, const char *msg, ...) ATTRIBUTE_PRINTF_2; @@ -110,4 +153,22 @@ enum { a meaningful value to be printed. */ FIRST_TOKEN_WITH_VALUE = PARAM_IS }; + + +/* For debugging purposes of gengtype itself! */ +extern int do_dump; +extern int do_debug; + +#if ENABLE_CHECKING +#define DBGPRINTF(Fmt,...) do {if(do_debug) \ + fprintf(stderr, "%s:%d: " Fmt "\n", \ + lbasename(__FILE__),__LINE__, ##__VA_ARGS__);} while(0) +void dbgprint_count_type_at (const char*fil, int lin, const char*msg, type_p t); +#define DBGPRINT_COUNT_TYPE(Msg,Ty) do{if (do_debug) \ + dbgprint_count_type_at (__FILE__, __LINE__, Msg, Ty);}while(0) +#else +#define DBGPRINTF(Fmt,...) do {/*nodbgrintf*/} while(0) +#define DBGPRINT_COUNT_TYPE(Msg,Ty) do{/*nodbgprint_count_type*/}while(0) +#endif /*ENABLE_CHECKING*/ + #endif Index: gcc-gengtypeincr-trunk/gcc/Makefile.in =================================================================== --- gcc-gengtypeincr-trunk/gcc/Makefile.in (revision 163987) +++ gcc-gengtypeincr-trunk/gcc/Makefile.in (working copy) @@ -837,6 +837,7 @@ DATESTAMP_c := $(shell cat $(DATESTAMP)) ifeq (,$(wildcard $(REVISION))) REVISION_c := +REVISION := else REVISION_c := $(shell cat $(REVISION)) endif @@ -2245,11 +2246,7 @@ gcc-options.o: options.c $(CONFIG_H) $(SYSTEM_H) c dumpvers: dumpvers.c -ifdef REVISION_c version.o: version.c version.h $(REVISION) $(DATESTAMP) $(BASEVER) $(DEVPHASE) -else -version.o: version.c version.h $(DATESTAMP) $(BASEVER) $(DEVPHASE) -endif $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ -DBASEVER=$(BASEVER_s) -DDATESTAMP=$(DATESTAMP_s) \ -DREVISION=$(REVISION_s) \ @@ -3809,7 +3806,7 @@ s-gtyp-input: Makefile s-gtype: build/gengtype$(build_exeext) $(filter-out [%], $(GTFILES)) \ gtyp-input.list - $(RUN_GEN) build/gengtype$(build_exeext) $(srcdir) gtyp-input.list + $(RUN_GEN) build/gengtype$(build_exeext) -S $(srcdir) -I gtyp-input.list $(STAMP) s-gtype generated_files = config.h tm.h $(TM_P_H) $(TM_H) multilib.h \ @@ -3829,6 +3826,15 @@ build/%.o : # dependencies provided by explicit r $(COMPILER_FOR_BUILD) -c $(BUILD_COMPILERFLAGS) $(BUILD_CPPFLAGS) \ -o $@ $< +## build/version.o is compiled by the $(COMPILER_FOR_BUILD) but needs +## several C macro definitions, just like version.o +build/version.o: version.c version.h $(REVISION) $(DATESTAMP) $(BASEVER) $(DEVPHASE) + $(COMPILER_FOR_BUILD) -c $(BUILD_COMPILERFLAGS) $(BUILD_CPPFLAGS) \ + -DBASEVER=$(BASEVER_s) -DDATESTAMP=$(DATESTAMP_s) \ + -DREVISION=$(REVISION_s) \ + -DDEVPHASE=$(DEVPHASE_s) -DPKGVERSION=$(PKGVERSION_s) \ + -DBUGURL=$(BUGURL_s) -o $@ $< + # Header dependencies for the programs that generate source code. # These are library modules... build/errors.o : errors.c $(BCONFIG_H) $(SYSTEM_H) errors.h @@ -3940,7 +3946,8 @@ $(genprog:%=build/gen%$(build_exeext)): $(BUILD_ER build/genautomata$(build_exeext) : BUILD_LIBS += -lm # These programs are not linked with the MD reader. -build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o +build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o \ + build/version.o build/genhooks$(build_exeext) : $(BUILD_ERRORS) # Generated source files for gengtype.