1 # Copyright (C) 2002, 2004, 2006, 2008, 2010 Free Software Foundation,
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2, or (at your option)
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 ###############################################################
18 # The main copy of this file is in Automake's CVS repository. #
19 # Updates should be sent to automake-patches@gnu.org. #
20 ###############################################################
22 package Automake::Channels;
26 Automake::Channels - support functions for error and warning management
30 use Automake::Channels;
32 # Register a channel to output warnings about unused variables.
33 register_channel 'unused', type => 'warning';
35 # Register a channel for system errors.
36 register_channel 'system', type => 'error', exit_code => 4;
38 # Output a message on channel 'unused'.
39 msg 'unused', "$file:$line", "unused variable `$var'";
41 # Make the 'unused' channel silent.
42 setup_channel 'unused', silent => 1;
44 # Turn on all channels of type 'warning'.
45 setup_channel_type 'warning', silent => 0;
47 # Redirect all channels to push messages on a Thread::Queue using
48 # the specified serialization key.
49 setup_channel_queue $queue, $key;
51 # Output a message pending in a Thread::Queue.
52 pop_channel_queue $queue;
54 # Treat all warnings as errors.
55 $warnings_are_errors = 1;
57 # Exit with the greatest exit code encountered so far.
62 This perl module provides support functions for handling diagnostic
63 channels in programs. Channels can be registered to convey fatal,
64 error, warning, or debug messages. Each channel has various options
65 (e.g. is the channel silent, should duplicate messages be removed,
66 etc.) that can also be overridden on a per-message basis.
76 use vars qw (@ISA @EXPORT %channels $me);
79 @EXPORT = qw ($exit_code $warnings_are_errors
80 &reset_local_duplicates &reset_global_duplicates
81 ®ister_channel &msg &exists_channel &channel_type
82 &setup_channel &setup_channel_type
83 &dup_channel_setup &drop_channel_setup
84 &buffer_messages &flush_messages
85 &setup_channel_queue &pop_channel_queue
87 UP_NONE UP_TEXT UP_LOC_TEXT);
91 =head2 Global Variables
97 The greatest exit code seen so far. C<$exit_code> is updated from
98 the C<exit_code> options of C<fatal> and C<error> channels.
102 use vars qw ($exit_code);
105 =item C<$warnings_are_errors>
107 Set this variable to 1 if warning messages should be treated as
108 errors (i.e. if they should update C<$exit_code>).
112 use vars qw ($warnings_are_errors);
113 $warnings_are_errors = 0;
121 =item C<UP_NONE>, C<UP_TEXT>, C<UP_LOC_TEXT>
123 Possible values for the C<uniq_part> options. This selects the part
124 of the message that should be considered when filtering out duplicates.
125 If C<UP_LOC_TEXT> is used, the location and the explanation message
126 are used for filtering. If C<UP_TEXT> is used, only the explanation
127 message is used (so the same message will be filtered out if it appears
128 at different locations). C<UP_NONE> means that duplicate messages
133 use constant UP_NONE => 0;
134 use constant UP_TEXT => 1;
135 use constant UP_LOC_TEXT => 2;
137 =item C<US_LOCAL>, C<US_GLOBAL>
139 Possible values for the C<uniq_scope> options.
140 Use C<US_GLOBAL> for error messages that should be printed only
141 once during the execution of the program, C<US_LOCAL> for message that
142 should be printed only once per file. (Actually, C<Channels> does not
143 do this now when files are changed, it relies on you calling
144 C<reset_local_duplicates> when this happens.)
148 # possible values for uniq_scope
149 use constant US_LOCAL => 0;
150 use constant US_GLOBAL => 1;
156 Channels accept the options described below. These options can be
157 passed as a hash to the C<register_channel>, C<setup_channel>, and C<msg>
158 functions. The possible keys, with their default value are:
162 =item C<type =E<gt> 'warning'>
164 The type of the channel. One of C<'debug'>, C<'warning'>, C<'error'>, or
165 C<'fatal'>. Fatal messages abort the program when they are output.
166 Error messages update the exit status. Debug and warning messages are
167 harmless, except that warnings can be treated as errors of
168 C<$warnings_are_errors> is set.
170 =item C<exit_code =E<gt> 1>
172 The value to update C<$exit_code> with when a fatal or error message
173 is emitted. C<$exit_code> is also updated for warnings output
174 when C<$warnings_are_errors> is set.
176 =item C<file =E<gt> \*STDERR>
178 The file where the error should be output.
180 =item C<silent =E<gt> 0>
182 Whether the channel should be silent. Use this do disable a
183 category of warning, for instance.
185 =item C<ordered =E<gt> 1>
187 Whether, with multi-threaded execution, the message should be queued
190 =item C<uniq_part =E<gt> UP_LOC_TEXT>
192 The part of the message subject to duplicate filtering. See the
193 documentation for the C<UP_NONE>, C<UP_TEXT>, and C<UP_LOC_TEXT>
196 C<uniq_part> can also be set to an arbitrary string that will be used
197 instead of the message when considering duplicates.
199 =item C<uniq_scope =E<gt> US_LOCAL>
201 The scope of duplicate filtering. See the documentation for the
202 C<US_LOCAL>, and C<US_GLOBAL> constants above.
204 =item C<header =E<gt> ''>
206 A string to prepend to each message emitted through this channel.
208 =item C<footer =E<gt> ''>
210 A string to append to each message emitted through this channel.
212 =item C<backtrace =E<gt> 0>
214 Die with a stack backtrace after displaying the message.
216 =item C<partial =E<gt> 0>
218 When set, indicates a partial message that should
219 be output along with the next message with C<partial> unset.
220 Several partial messages can be stacked this way.
222 Duplicate filtering will apply to the I<global> message resulting from
223 all I<partial> messages, using the options from the last (non-partial)
224 message. Linking associated messages is the main reason to use this
227 For instance the following messages
229 msg 'channel', 'foo:2', 'redefinition of A ...';
230 msg 'channel', 'foo:1', '... A previously defined here';
231 msg 'channel', 'foo:3', 'redefinition of A ...';
232 msg 'channel', 'foo:1', '... A previously defined here';
236 foo:2: redefinition of A ...
237 foo:1: ... A previously defined here
238 foo:3: redefinition of A ...
240 where the duplicate "I<... A previously defined here>" has been
243 Linking these messages using C<partial> as follows will prevent the
244 fourth message to disappear.
246 msg 'channel', 'foo:2', 'redefinition of A ...', partial => 1;
247 msg 'channel', 'foo:1', '... A previously defined here';
248 msg 'channel', 'foo:3', 'redefinition of A ...', partial => 1;
249 msg 'channel', 'foo:1', '... A previously defined here';
251 Note that because the stack of C<partial> messages is printed with the
252 first non-C<partial> message, most options of C<partial> messages will
259 use vars qw (%_default_options %_global_duplicate_messages
260 %_local_duplicate_messages);
262 # Default options for a channel.
272 uniq_scope => US_LOCAL,
273 uniq_part => UP_LOC_TEXT,
280 # Filled with output messages as keys, to detect duplicates.
281 # The value associated with each key is the number of occurrences
283 %_local_duplicate_messages = ();
284 %_global_duplicate_messages = ();
286 sub _reset_duplicates (\%)
290 foreach my $k (keys %$ref)
303 =item C<reset_local_duplicates ()>
305 Reset local duplicate messages (see C<US_LOCAL>), and
306 return the number of messages that have been filtered out.
310 sub reset_local_duplicates ()
312 return _reset_duplicates %_local_duplicate_messages;
315 =item C<reset_global_duplicates ()>
317 Reset local duplicate messages (see C<US_GLOBAL>), and
318 return the number of messages that have been filtered out.
322 sub reset_global_duplicates ()
324 return _reset_duplicates %_global_duplicate_messages;
327 sub _merge_options (\%%)
329 my ($hash, %options) = @_;
332 foreach (keys %options)
334 if (exists $hash->{$_})
336 $hash->{$_} = $options{$_}
340 confess "unknown option `$_'";
343 if ($hash->{'ordered'})
345 confess "fatal messages cannot be ordered"
346 if $hash->{'type'} eq 'fatal';
347 confess "backtrace cannot be output on ordered messages"
348 if $hash->{'backtrace'};
352 =item C<register_channel ($name, [%options])>
354 Declare channel C<$name>, and override the default options
355 with those listed in C<%options>.
359 sub register_channel ($;%)
361 my ($name, %options) = @_;
362 my %channel_opts = %_default_options;
363 _merge_options %channel_opts, %options;
364 $channels{$name} = \%channel_opts;
367 =item C<exists_channel ($name)>
369 Returns true iff channel C<$name> has been registered.
373 sub exists_channel ($)
376 return exists $channels{$name};
379 =item C<channel_type ($name)>
381 Returns the type of channel C<$name> if it has been registered.
382 Returns the empty string otherwise.
389 return $channels{$name}{'type'} if exists_channel $name;
393 # _format_sub_message ($LEADER, $MESSAGE)
394 # ---------------------------------------
395 # Split $MESSAGE at new lines and add $LEADER to each line.
396 sub _format_sub_message ($$)
398 my ($leader, $message) = @_;
399 return $leader . join ("\n" . $leader, split ("\n", $message)) . "\n";
402 # _format_message ($LOCATION, $MESSAGE, %OPTIONS)
403 # -----------------------------------------------
404 # Format the message. Return a string ready to print.
405 sub _format_message ($$%)
407 my ($location, $message, %opts) = @_;
411 # If $LOCATION is a reference, assume it's an instance of the
412 # Automake::Location class and display contexts.
413 my $loc = $location->get || $me;
414 $msg = _format_sub_message ("$loc: ", $opts{'header'}
415 . $message . $opts{'footer'});
416 for my $pair ($location->get_contexts)
418 $msg .= _format_sub_message ($pair->[0] . ": ", $pair->[1]);
424 $msg = _format_sub_message ("$location: ", $opts{'header'}
425 . $message . $opts{'footer'});
430 # _enqueue ($QUEUE, $KEY, $UNIQ_SCOPE, $TO_FILTER, $MSG, $FILE)
431 # -------------------------------------------------------------
432 # Push message on a queue, to be processed by another thread.
433 sub _enqueue ($$$$$$)
435 my ($queue, $key, $uniq_scope, $to_filter, $msg, $file) = @_;
436 $queue->enqueue ($key, $msg, $to_filter, $uniq_scope);
437 confess "message queuing works only for STDERR"
438 if $file ne \*STDERR;
443 # Pop a message from a queue, and print, similarly to how
444 # _print_message would do it. Return 0 if the queue is
445 # empty. Note that the key has already been dequeued.
449 my $msg = $queue->dequeue || return 0;
450 my $to_filter = $queue->dequeue;
451 my $uniq_scope = $queue->dequeue;
454 if ($to_filter ne '')
456 # Do we want local or global uniqueness?
458 if ($uniq_scope == US_LOCAL)
460 $dups = \%_local_duplicate_messages;
462 elsif ($uniq_scope == US_GLOBAL)
464 $dups = \%_global_duplicate_messages;
468 confess "unknown value for uniq_scope: " . $uniq_scope;
471 # Update the hash of messages.
472 if (exists $dups->{$to_filter})
474 ++$dups->{$to_filter};
479 $dups->{$to_filter} = 0;
487 # Store partial messages here. (See the 'partial' option.)
488 use vars qw ($partial);
491 # _print_message ($LOCATION, $MESSAGE, %OPTIONS)
492 # ----------------------------------------------
493 # Format the message, check duplicates, and print it.
494 sub _print_message ($$%)
496 my ($location, $message, %opts) = @_;
498 return 0 if ($opts{'silent'});
500 my $msg = _format_message ($location, $message, %opts);
501 if ($opts{'partial'})
503 # Incomplete message. Store, don't print.
509 # Prefix with any partial message send so far.
510 $msg = $partial . $msg;
514 # Check for duplicate message if requested.
516 if ($opts{'uniq_part'} ne UP_NONE)
518 # Which part of the error should we match?
519 if ($opts{'uniq_part'} eq UP_TEXT)
521 $to_filter = $message;
523 elsif ($opts{'uniq_part'} eq UP_LOC_TEXT)
529 $to_filter = $opts{'uniq_part'};
532 # Do we want local or global uniqueness?
534 if ($opts{'uniq_scope'} == US_LOCAL)
536 $dups = \%_local_duplicate_messages;
538 elsif ($opts{'uniq_scope'} == US_GLOBAL)
540 $dups = \%_global_duplicate_messages;
544 confess "unknown value for uniq_scope: " . $opts{'uniq_scope'};
547 # Update the hash of messages.
548 if (exists $dups->{$to_filter})
550 ++$dups->{$to_filter};
555 $dups->{$to_filter} = 0;
558 my $file = $opts{'file'};
559 if ($opts{'ordered'} && $opts{'queue'})
561 _enqueue ($opts{'queue'}, $opts{'queue_key'}, $opts{'uniq_scope'},
562 $to_filter, $msg, $file);
571 =item C<msg ($channel, $location, $message, [%options])>
573 Emit a message on C<$channel>, overriding some options of the channel with
574 those specified in C<%options>. Obviously C<$channel> must have been
575 registered with C<register_channel>.
577 C<$message> is the text of the message, and C<$location> is a location
578 associated to the message.
580 For instance to complain about some unused variable C<mumble>
581 declared at line 10 in F<foo.c>, one could do:
583 msg 'unused', 'foo.c:10', "unused variable `mumble'";
585 If channel C<unused> is not silent (and if this message is not a duplicate),
586 the following would be output:
588 foo.c:10: unused variable `mumble'
590 C<$location> can also be an instance of C<Automake::Location>. In this
591 case, the stack of contexts will be displayed in addition.
593 If C<$message> contains newline characters, C<$location> is prepended
594 to each line. For instance,
596 msg 'error', 'somewhere', "1st line\n2nd line";
603 If C<$location> is an empty string, it is replaced by the name of the
604 program. Actually, if you don't use C<%options>, you can even
605 elide the empty C<$location>. Thus
607 msg 'fatal', '', 'fatal error';
608 msg 'fatal', 'fatal error';
612 progname: fatal error
617 use vars qw (@backlog %buffering);
619 # See buffer_messages() and flush_messages() below.
620 %buffering = (); # The map of channel types to buffer.
621 @backlog = (); # The buffer of messages.
625 my ($channel, $location, $message, %options) = @_;
627 if (! defined $message)
629 $message = $location;
633 confess "unknown channel $channel" unless exists $channels{$channel};
635 my %opts = %{$channels{$channel}};
636 _merge_options (%opts, %options);
638 if (exists $buffering{$opts{'type'}})
640 push @backlog, [$channel, $location->clone, $message, %options];
644 # Print the message if needed.
645 if (_print_message ($location, $message, %opts))
647 # Adjust exit status.
648 if ($opts{'type'} eq 'error'
649 || $opts{'type'} eq 'fatal'
650 || ($opts{'type'} eq 'warning' && $warnings_are_errors))
652 my $es = $opts{'exit_code'};
653 $exit_code = $es if $es > $exit_code;
656 # Die on fatal messages.
657 confess if $opts{'backtrace'};
658 if ($opts{'type'} eq 'fatal')
660 # flush messages explicitly here, needed in worker threads.
668 =item C<setup_channel ($channel, %options)>
670 Override the options of C<$channel> with those specified by C<%options>.
674 sub setup_channel ($%)
676 my ($name, %opts) = @_;
677 confess "channel $name doesn't exist" unless exists $channels{$name};
678 _merge_options %{$channels{$name}}, %opts;
681 =item C<setup_channel_type ($type, %options)>
683 Override the options of any channel of type C<$type>
684 with those specified by C<%options>.
688 sub setup_channel_type ($%)
690 my ($type, %opts) = @_;
691 foreach my $channel (keys %channels)
693 setup_channel $channel, %opts
694 if $channels{$channel}{'type'} eq $type;
698 =item C<dup_channel_setup ()>, C<drop_channel_setup ()>
700 Sometimes it is necessary to make temporary modifications to channels.
701 For instance one may want to disable a warning while processing a
702 particular file, and then restore the initial setup. These two
703 functions make it easy: C<dup_channel_setup ()> saves a copy of the
704 current configuration for later restoration by
705 C<drop_channel_setup ()>.
707 You can think of this as a stack of configurations whose first entry
708 is the active one. C<dup_channel_setup ()> duplicates the first
709 entry, while C<drop_channel_setup ()> just deletes it.
713 use vars qw (@_saved_channels @_saved_werrors);
714 @_saved_channels = ();
715 @_saved_werrors = ();
717 sub dup_channel_setup ()
720 foreach my $k1 (keys %channels)
722 $channels_copy{$k1} = {%{$channels{$k1}}};
724 push @_saved_channels, \%channels_copy;
725 push @_saved_werrors, $warnings_are_errors;
728 sub drop_channel_setup ()
730 my $saved = pop @_saved_channels;
732 $warnings_are_errors = pop @_saved_werrors;
735 =item C<buffer_messages (@types)>, C<flush_messages ()>
737 By default, when C<msg> is called, messages are processed immediately.
739 Sometimes it is necessary to delay the output of messages.
740 For instance you might want to make diagnostics before
741 channels have been completely configured.
743 After C<buffer_messages(@types)> has been called, messages sent with
744 C<msg> to a channel whose type is listed in C<@types> will be stored in a
745 list for later processing.
747 This backlog of messages is processed when C<flush_messages> is
748 called, with the current channel options (not the options in effect,
749 at the time of C<msg>). So for instance, if some channel was silenced
750 in the meantime, messages to this channel will not be printed.
752 C<flush_messages> cancels the effect of C<buffer_messages>. Following
753 calls to C<msg> are processed immediately as usual.
757 sub buffer_messages (@)
759 foreach my $type (@_)
761 $buffering{$type} = 1;
765 sub flush_messages ()
768 foreach my $args (@backlog)
775 =item C<setup_channel_queue ($queue, $key)>
777 Set the queue to fill for each channel that is ordered,
778 and the key to use for serialization.
781 sub setup_channel_queue ($$)
783 my ($queue, $key) = @_;
784 foreach my $channel (keys %channels)
786 setup_channel $channel, queue => $queue, queue_key => $key
787 if $channels{$channel}{'ordered'};
791 =item C<pop_channel_queue ($queue)>
793 pop a message off the $queue; the key has already been popped.
796 sub pop_channel_queue ($)
799 return _dequeue ($queue);
806 L<Automake::Location>
810 Written by Alexandre Duret-Lutz E<lt>F<adl@gnu.org>E<gt>.
816 ### Setup "GNU" style for perl-mode and cperl-mode.
818 ## perl-indent-level: 2
819 ## perl-continued-statement-offset: 2
820 ## perl-continued-brace-offset: 0
821 ## perl-brace-offset: 0
822 ## perl-brace-imaginary-offset: 0
823 ## perl-label-offset: -2
824 ## cperl-indent-level: 2
825 ## cperl-brace-offset: 0
826 ## cperl-continued-brace-offset: 0
827 ## cperl-label-offset: -2
828 ## cperl-extra-newline-before-brace: t
829 ## cperl-merge-trailing-else: nil
830 ## cperl-continued-statement-offset: 2