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 are treated as errors if
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.
207 With partial messages, only the first part will have C<header>
210 =item C<footer =E<gt> ''>
212 A string to append to each message emitted through this channel.
213 With partial messages, only the final part will have C<footer>
216 =item C<backtrace =E<gt> 0>
218 Die with a stack backtrace after displaying the message.
220 =item C<partial =E<gt> 0>
222 When set, indicates a partial message that should
223 be output along with the next message with C<partial> unset.
224 Several partial messages can be stacked this way.
226 Duplicate filtering will apply to the I<global> message resulting from
227 all I<partial> messages, using the options from the last (non-partial)
228 message. Linking associated messages is the main reason to use this
231 For instance the following messages
233 msg 'channel', 'foo:2', 'redefinition of A ...';
234 msg 'channel', 'foo:1', '... A previously defined here';
235 msg 'channel', 'foo:3', 'redefinition of A ...';
236 msg 'channel', 'foo:1', '... A previously defined here';
240 foo:2: redefinition of A ...
241 foo:1: ... A previously defined here
242 foo:3: redefinition of A ...
244 where the duplicate "I<... A previously defined here>" has been
247 Linking these messages using C<partial> as follows will prevent the
248 fourth message to disappear.
250 msg 'channel', 'foo:2', 'redefinition of A ...', partial => 1;
251 msg 'channel', 'foo:1', '... A previously defined here';
252 msg 'channel', 'foo:3', 'redefinition of A ...', partial => 1;
253 msg 'channel', 'foo:1', '... A previously defined here';
255 Note that because the stack of C<partial> messages is printed with the
256 first non-C<partial> message, most options of C<partial> messages will
263 use vars qw (%_default_options %_global_duplicate_messages
264 %_local_duplicate_messages);
266 # Default options for a channel.
276 uniq_scope => US_LOCAL,
277 uniq_part => UP_LOC_TEXT,
284 # Filled with output messages as keys, to detect duplicates.
285 # The value associated with each key is the number of occurrences
287 %_local_duplicate_messages = ();
288 %_global_duplicate_messages = ();
290 sub _reset_duplicates (\%)
294 foreach my $k (keys %$ref)
307 =item C<reset_local_duplicates ()>
309 Reset local duplicate messages (see C<US_LOCAL>), and
310 return the number of messages that have been filtered out.
314 sub reset_local_duplicates ()
316 return _reset_duplicates %_local_duplicate_messages;
319 =item C<reset_global_duplicates ()>
321 Reset local duplicate messages (see C<US_GLOBAL>), and
322 return the number of messages that have been filtered out.
326 sub reset_global_duplicates ()
328 return _reset_duplicates %_global_duplicate_messages;
331 sub _merge_options (\%%)
333 my ($hash, %options) = @_;
336 foreach (keys %options)
338 if (exists $hash->{$_})
340 $hash->{$_} = $options{$_}
344 confess "unknown option `$_'";
347 if ($hash->{'ordered'})
349 confess "fatal messages cannot be ordered"
350 if $hash->{'type'} eq 'fatal';
351 confess "backtrace cannot be output on ordered messages"
352 if $hash->{'backtrace'};
356 =item C<register_channel ($name, [%options])>
358 Declare channel C<$name>, and override the default options
359 with those listed in C<%options>.
363 sub register_channel ($;%)
365 my ($name, %options) = @_;
366 my %channel_opts = %_default_options;
367 _merge_options %channel_opts, %options;
368 $channels{$name} = \%channel_opts;
371 =item C<exists_channel ($name)>
373 Returns true iff channel C<$name> has been registered.
377 sub exists_channel ($)
380 return exists $channels{$name};
383 =item C<channel_type ($name)>
385 Returns the type of channel C<$name> if it has been registered.
386 Returns the empty string otherwise.
393 return $channels{$name}{'type'} if exists_channel $name;
397 # _format_sub_message ($LEADER, $MESSAGE)
398 # ---------------------------------------
399 # Split $MESSAGE at new lines and add $LEADER to each line.
400 sub _format_sub_message ($$)
402 my ($leader, $message) = @_;
403 return $leader . join ("\n" . $leader, split ("\n", $message)) . "\n";
406 # Store partial messages here. (See the 'partial' option.)
407 use vars qw ($partial);
410 # _format_message ($LOCATION, $MESSAGE, %OPTIONS)
411 # -----------------------------------------------
412 # Format the message. Return a string ready to print.
413 sub _format_message ($$%)
415 my ($location, $message, %opts) = @_;
416 my $msg = ($partial eq '' ? $opts{'header'} : '') . $message
417 . ($opts{'partial'} ? '' : $opts{'footer'});
420 # If $LOCATION is a reference, assume it's an instance of the
421 # Automake::Location class and display contexts.
422 my $loc = $location->get || $me;
423 $msg = _format_sub_message ("$loc: ", $msg);
424 for my $pair ($location->get_contexts)
426 $msg .= _format_sub_message ($pair->[0] . ": ", $pair->[1]);
432 $msg = _format_sub_message ("$location: ", $msg);
437 # _enqueue ($QUEUE, $KEY, $UNIQ_SCOPE, $TO_FILTER, $MSG, $FILE)
438 # -------------------------------------------------------------
439 # Push message on a queue, to be processed by another thread.
440 sub _enqueue ($$$$$$)
442 my ($queue, $key, $uniq_scope, $to_filter, $msg, $file) = @_;
443 $queue->enqueue ($key, $msg, $to_filter, $uniq_scope);
444 confess "message queuing works only for STDERR"
445 if $file ne \*STDERR;
450 # Pop a message from a queue, and print, similarly to how
451 # _print_message would do it. Return 0 if the queue is
452 # empty. Note that the key has already been dequeued.
456 my $msg = $queue->dequeue || return 0;
457 my $to_filter = $queue->dequeue;
458 my $uniq_scope = $queue->dequeue;
461 if ($to_filter ne '')
463 # Do we want local or global uniqueness?
465 if ($uniq_scope == US_LOCAL)
467 $dups = \%_local_duplicate_messages;
469 elsif ($uniq_scope == US_GLOBAL)
471 $dups = \%_global_duplicate_messages;
475 confess "unknown value for uniq_scope: " . $uniq_scope;
478 # Update the hash of messages.
479 if (exists $dups->{$to_filter})
481 ++$dups->{$to_filter};
486 $dups->{$to_filter} = 0;
494 # _print_message ($LOCATION, $MESSAGE, %OPTIONS)
495 # ----------------------------------------------
496 # Format the message, check duplicates, and print it.
497 sub _print_message ($$%)
499 my ($location, $message, %opts) = @_;
501 return 0 if ($opts{'silent'});
503 my $msg = _format_message ($location, $message, %opts);
504 if ($opts{'partial'})
506 # Incomplete message. Store, don't print.
512 # Prefix with any partial message send so far.
513 $msg = $partial . $msg;
517 msg ('note', '', 'warnings are treated as errors', uniq_scope => US_GLOBAL)
518 if ($opts{'type'} eq 'warning' && $warnings_are_errors);
520 # Check for duplicate message if requested.
522 if ($opts{'uniq_part'} ne UP_NONE)
524 # Which part of the error should we match?
525 if ($opts{'uniq_part'} eq UP_TEXT)
527 $to_filter = $message;
529 elsif ($opts{'uniq_part'} eq UP_LOC_TEXT)
535 $to_filter = $opts{'uniq_part'};
538 # Do we want local or global uniqueness?
540 if ($opts{'uniq_scope'} == US_LOCAL)
542 $dups = \%_local_duplicate_messages;
544 elsif ($opts{'uniq_scope'} == US_GLOBAL)
546 $dups = \%_global_duplicate_messages;
550 confess "unknown value for uniq_scope: " . $opts{'uniq_scope'};
553 # Update the hash of messages.
554 if (exists $dups->{$to_filter})
556 ++$dups->{$to_filter};
561 $dups->{$to_filter} = 0;
564 my $file = $opts{'file'};
565 if ($opts{'ordered'} && $opts{'queue'})
567 _enqueue ($opts{'queue'}, $opts{'queue_key'}, $opts{'uniq_scope'},
568 $to_filter, $msg, $file);
577 =item C<msg ($channel, $location, $message, [%options])>
579 Emit a message on C<$channel>, overriding some options of the channel with
580 those specified in C<%options>. Obviously C<$channel> must have been
581 registered with C<register_channel>.
583 C<$message> is the text of the message, and C<$location> is a location
584 associated to the message.
586 For instance to complain about some unused variable C<mumble>
587 declared at line 10 in F<foo.c>, one could do:
589 msg 'unused', 'foo.c:10', "unused variable `mumble'";
591 If channel C<unused> is not silent (and if this message is not a duplicate),
592 the following would be output:
594 foo.c:10: unused variable `mumble'
596 C<$location> can also be an instance of C<Automake::Location>. In this
597 case, the stack of contexts will be displayed in addition.
599 If C<$message> contains newline characters, C<$location> is prepended
600 to each line. For instance,
602 msg 'error', 'somewhere', "1st line\n2nd line";
609 If C<$location> is an empty string, it is replaced by the name of the
610 program. Actually, if you don't use C<%options>, you can even
611 elide the empty C<$location>. Thus
613 msg 'fatal', '', 'fatal error';
614 msg 'fatal', 'fatal error';
618 progname: fatal error
623 use vars qw (@backlog %buffering);
625 # See buffer_messages() and flush_messages() below.
626 %buffering = (); # The map of channel types to buffer.
627 @backlog = (); # The buffer of messages.
631 my ($channel, $location, $message, %options) = @_;
633 if (! defined $message)
635 $message = $location;
639 confess "unknown channel $channel" unless exists $channels{$channel};
641 my %opts = %{$channels{$channel}};
642 _merge_options (%opts, %options);
644 if (exists $buffering{$opts{'type'}})
646 push @backlog, [$channel, $location->clone, $message, %options];
650 # Print the message if needed.
651 if (_print_message ($location, $message, %opts))
653 # Adjust exit status.
654 if ($opts{'type'} eq 'error'
655 || $opts{'type'} eq 'fatal'
656 || ($opts{'type'} eq 'warning' && $warnings_are_errors))
658 my $es = $opts{'exit_code'};
659 $exit_code = $es if $es > $exit_code;
662 # Die on fatal messages.
663 confess if $opts{'backtrace'};
664 if ($opts{'type'} eq 'fatal')
666 # flush messages explicitly here, needed in worker threads.
674 =item C<setup_channel ($channel, %options)>
676 Override the options of C<$channel> with those specified by C<%options>.
680 sub setup_channel ($%)
682 my ($name, %opts) = @_;
683 confess "unknown channel $name" unless exists $channels{$name};
684 _merge_options %{$channels{$name}}, %opts;
687 =item C<setup_channel_type ($type, %options)>
689 Override the options of any channel of type C<$type>
690 with those specified by C<%options>.
694 sub setup_channel_type ($%)
696 my ($type, %opts) = @_;
697 foreach my $channel (keys %channels)
699 setup_channel $channel, %opts
700 if $channels{$channel}{'type'} eq $type;
704 =item C<dup_channel_setup ()>, C<drop_channel_setup ()>
706 Sometimes it is necessary to make temporary modifications to channels.
707 For instance one may want to disable a warning while processing a
708 particular file, and then restore the initial setup. These two
709 functions make it easy: C<dup_channel_setup ()> saves a copy of the
710 current configuration for later restoration by
711 C<drop_channel_setup ()>.
713 You can think of this as a stack of configurations whose first entry
714 is the active one. C<dup_channel_setup ()> duplicates the first
715 entry, while C<drop_channel_setup ()> just deletes it.
719 use vars qw (@_saved_channels @_saved_werrors);
720 @_saved_channels = ();
721 @_saved_werrors = ();
723 sub dup_channel_setup ()
726 foreach my $k1 (keys %channels)
728 $channels_copy{$k1} = {%{$channels{$k1}}};
730 push @_saved_channels, \%channels_copy;
731 push @_saved_werrors, $warnings_are_errors;
734 sub drop_channel_setup ()
736 my $saved = pop @_saved_channels;
738 $warnings_are_errors = pop @_saved_werrors;
741 =item C<buffer_messages (@types)>, C<flush_messages ()>
743 By default, when C<msg> is called, messages are processed immediately.
745 Sometimes it is necessary to delay the output of messages.
746 For instance you might want to make diagnostics before
747 channels have been completely configured.
749 After C<buffer_messages(@types)> has been called, messages sent with
750 C<msg> to a channel whose type is listed in C<@types> will be stored in a
751 list for later processing.
753 This backlog of messages is processed when C<flush_messages> is
754 called, with the current channel options (not the options in effect,
755 at the time of C<msg>). So for instance, if some channel was silenced
756 in the meantime, messages to this channel will not be printed.
758 C<flush_messages> cancels the effect of C<buffer_messages>. Following
759 calls to C<msg> are processed immediately as usual.
763 sub buffer_messages (@)
765 foreach my $type (@_)
767 $buffering{$type} = 1;
771 sub flush_messages ()
774 foreach my $args (@backlog)
781 =item C<setup_channel_queue ($queue, $key)>
783 Set the queue to fill for each channel that is ordered,
784 and the key to use for serialization.
787 sub setup_channel_queue ($$)
789 my ($queue, $key) = @_;
790 foreach my $channel (keys %channels)
792 setup_channel $channel, queue => $queue, queue_key => $key
793 if $channels{$channel}{'ordered'};
797 =item C<pop_channel_queue ($queue)>
799 pop a message off the $queue; the key has already been popped.
802 sub pop_channel_queue ($)
805 return _dequeue ($queue);
812 L<Automake::Location>
816 Written by Alexandre Duret-Lutz E<lt>F<adl@gnu.org>E<gt>.
822 ### Setup "GNU" style for perl-mode and cperl-mode.
824 ## perl-indent-level: 2
825 ## perl-continued-statement-offset: 2
826 ## perl-continued-brace-offset: 0
827 ## perl-brace-offset: 0
828 ## perl-brace-imaginary-offset: 0
829 ## perl-label-offset: -2
830 ## cperl-indent-level: 2
831 ## cperl-brace-offset: 0
832 ## cperl-continued-brace-offset: 0
833 ## cperl-label-offset: -2
834 ## cperl-extra-newline-before-brace: t
835 ## cperl-merge-trailing-else: nil
836 ## cperl-continued-statement-offset: 2