On Tue, 29 Sep 2009, Joel E. Denny wrote: > On Sat, 19 Sep 2009, Alex Rozenman wrote:
> > +/* Generate a message aligned by an indent. > > + When *indent == 0, assign message's indent to *indent, > > + When *indent > 0, align the message by *indent value. */ > > +void warn_at_indent (location loc, unsigned *indent, > > + char const *format, ...) > > + __attribute__ ((__format__ (__printf__, 3, 4))); > > + > > Rather than forcing the caller to deal with the indentation variable, it > seems like it would be cleaner if warn_at automatically set the > indentation level in a static global variable. Any subsequent > warn_at_indent invocation would automatically use that indentation level. > And the next warn_at invocation would reset it, etc. While I still think that would be better than the current implementation, there's of course a bigger problem where neither implementation is good. It appears that named reference message blocks have the nice property that the location printed on the first line is not usually much shorter than the locations printed on subsequent lines. When that's not the case, neither your implementation nor my proposed one would indent properly. If we try to use indentation in error messages for other parts of Bison where that nice property might rarely hold, my proposed implementation is going to be hopeless. At least with your implementation we can adjust the caller to try to compute the necessary indentation all up front and store it in the indentation variable before any invocation of complain_at or complaint_at_indent. But that sounds painful to have to do every time. Instead, all indentation work ought to be performed within complain.c. Here's an example of how a better interface might be used: // Clear any previously buffered message, // and set indentation level to 0. error_start (); complain_at_save (loc0, msg0); // msg0 saved at indentation level 0. error_indent (); complain_at_save (loc1, msg1); // msg1 saved at indentation level 1. complain_at_save (loc2, msg2); // msg2 saved at indentation level 1. complain_at_save (loc3, msg3); // msg3 saved at indentation level 1. error_indent (); complain_at_save (loc4, msg4); // msg4 saved at indentation level 2. complain_at_save (loc5, msg5); // msg5 saved at indentation level 2. error_unindent (); complain_at_save (loc6, msg6); // msg6 saved at indentation level 1. error_end (); // Entire message block is printed. ... // msg9 prints immediately at level 0 ignoring whatever is currently // saved. For example, there may have been some sort of failure while // building a previous error message block. complain_at (loc9, msg9); Implementing the message buffering will be a little tedious, but if we want automatic indentation, I think something like this is the robust way to do it.
