1 # Copyright (C) 2002, 2004, 2006, 2008 Free Software Foundation, Inc.
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2, or (at your option)
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 ###############################################################
19 # The main copy of this file is in Automake's CVS repository. #
20 # Updates should be sent to automake-patches@gnu.org. #
21 ###############################################################
23 package Autom4te
::Channels
;
27 Autom4te::Channels - support functions for error and warning management
31 use Autom4te::Channels;
33 # Register a channel to output warnings about unused variables.
34 register_channel 'unused', type => 'warning';
36 # Register a channel for system errors.
37 register_channel 'system', type => 'error', exit_code => 4;
39 # Output a message on channel 'unused'.
40 msg 'unused', "$file:$line", "unused variable `$var'";
42 # Make the 'unused' channel silent.
43 setup_channel 'unused', silent => 1;
45 # Turn on all channels of type 'warning'.
46 setup_channel_type 'warning', silent => 0;
48 # Redirect all channels to push messages on a Thread::Queue using
49 # the specified serialization key.
50 setup_channel_queue $queue, $key;
52 # Output a message pending in a Thread::Queue.
53 pop_channel_queue $queue;
55 # Treat all warnings as errors.
56 $warnings_are_errors = 1;
58 # Exit with the greatest exit code encountered so far.
63 This perl module provides support functions for handling diagnostic
64 channels in programs. Channels can be registered to convey fatal,
65 error, warning, or debug messages. Each channel has various options
66 (e.g. is the channel silent, should duplicate messages be removed,
67 etc.) that can also be overridden on a per-message basis.
77 use vars qw
(@ISA @EXPORT %channels $me);
80 @EXPORT = qw
($exit_code $warnings_are_errors
81 &reset_local_duplicates
&reset_global_duplicates
82 ®ister_channel
&msg
&exists_channel
&channel_type
83 &setup_channel
&setup_channel_type
84 &dup_channel_setup
&drop_channel_setup
85 &buffer_messages
&flush_messages
86 &setup_channel_queue
&pop_channel_queue
88 UP_NONE UP_TEXT UP_LOC_TEXT
);
92 =head2 Global Variables
98 The greatest exit code seen so far. C<$exit_code> is updated from
99 the C<exit_code> options of C<fatal> and C<error> channels.
103 use vars qw
($exit_code);
106 =item C<$warnings_are_errors>
108 Set this variable to 1 if warning messages should be treated as
109 errors (i.e. if they should update C<$exit_code>).
113 use vars qw
($warnings_are_errors);
114 $warnings_are_errors = 0;
122 =item C<UP_NONE>, C<UP_TEXT>, C<UP_LOC_TEXT>
124 Possible values for the C<uniq_part> options. This selects the part
125 of the message that should be considered when filtering out duplicates.
126 If C<UP_LOC_TEXT> is used, the location and the explanation message
127 are used for filtering. If C<UP_TEXT> is used, only the explanation
128 message is used (so the same message will be filtered out if it appears
129 at different locations). C<UP_NONE> means that duplicate messages
134 use constant UP_NONE
=> 0;
135 use constant UP_TEXT
=> 1;
136 use constant UP_LOC_TEXT
=> 2;
138 =item C<US_LOCAL>, C<US_GLOBAL>
140 Possible values for the C<uniq_scope> options.
141 Use C<US_GLOBAL> for error messages that should be printed only
142 once during the execution of the program, C<US_LOCAL> for message that
143 should be printed only once per file. (Actually, C<Channels> does not
144 do this now when files are changed, it relies on you calling
145 C<reset_local_duplicates> when this happens.)
149 # possible values for uniq_scope
150 use constant US_LOCAL
=> 0;
151 use constant US_GLOBAL
=> 1;
157 Channels accept the options described below. These options can be
158 passed as a hash to the C<register_channel>, C<setup_channel>, and C<msg>
159 functions. The possible keys, with their default value are:
163 =item C<type =E<gt> 'warning'>
165 The type of the channel. One of C<'debug'>, C<'warning'>, C<'error'>, or
166 C<'fatal'>. Fatal messages abort the program when they are output.
167 Error messages update the exit status. Debug and warning messages are
168 harmless, except that warnings can be treated as errors of
169 C<$warnings_are_errors> is set.
171 =item C<exit_code =E<gt> 1>
173 The value to update C<$exit_code> with when a fatal or error message
174 is emitted. C<$exit_code> is also updated for warnings output
175 when @<$warnings_are_errors> is set.
177 =item C<file =E<gt> \*STDERR>
179 The file where the error should be output.
181 =item C<silent =E<gt> 0>
183 Whether the channel should be silent. Use this do disable a
184 category of warning, for instance.
186 =item C<ordered =E<gt> 1>
188 Whether, with multi-threaded execution, the message should be queued
191 =item C<uniq_part =E<gt> UP_LOC_TEXT>
193 The part of the message subject to duplicate filtering. See the
194 documentation for the C<UP_NONE>, C<UP_TEXT>, and C<UP_LOC_TEXT>
197 C<uniq_part> can also be set to an arbitrary string that will be used
198 instead of the message when considering duplicates.
200 =item C<uniq_scope =E<gt> US_LOCAL>
202 The scope of duplicate filtering. See the documentation for the
203 C<US_LOCAL>, and C<US_GLOBAL> constants above.
205 =item C<header =E<gt> ''>
207 A string to prepend to each message emitted through this channel.
209 =item C<footer =E<gt> ''>
211 A string to append to each message emitted through this channel.
213 =item C<backtrace =E<gt> 0>
215 Die with a stack backtrace after displaying the message.
217 =item C<partial =E<gt> 0>
219 When set, indicates a partial message that should
220 be output along with the next message with C<partial> unset.
221 Several partial messages can be stacked this way.
223 Duplicate filtering will apply to the I<global> message resulting from
224 all I<partial> messages, using the options from the last (non-partial)
225 message. Linking associated messages is the main reason to use this
228 For instance the following messages
230 msg 'channel', 'foo:2', 'redefinition of A ...';
231 msg 'channel', 'foo:1', '... A previously defined here';
232 msg 'channel', 'foo:3', 'redefinition of A ...';
233 msg 'channel', 'foo:1', '... A previously defined here';
237 foo:2: redefinition of A ...
238 foo:1: ... A previously defined here
239 foo:3: redefinition of A ...
241 where the duplicate "I<... A previously defined here>" has been
244 Linking these messages using C<partial> as follows will prevent the
245 fourth message to disappear.
247 msg 'channel', 'foo:2', 'redefinition of A ...', partial => 1;
248 msg 'channel', 'foo:1', '... A previously defined here';
249 msg 'channel', 'foo:3', 'redefinition of A ...', partial => 1;
250 msg 'channel', 'foo:1', '... A previously defined here';
252 Note that because the stack of C<partial> messages is printed with the
253 first non-C<partial> message, most options of C<partial> messages will
260 use vars qw
(%_default_options %_global_duplicate_messages
261 %_local_duplicate_messages);
263 # Default options for a channel.
273 uniq_scope
=> US_LOCAL
,
274 uniq_part
=> UP_LOC_TEXT
,
281 # Filled with output messages as keys, to detect duplicates.
282 # The value associated with each key is the number of occurrences
284 %_local_duplicate_messages = ();
285 %_global_duplicate_messages = ();
287 sub _reset_duplicates
(\
%)
291 foreach my $k (keys %$ref)
304 =item C<reset_local_duplicates ()>
306 Reset local duplicate messages (see C<US_LOCAL>), and
307 return the number of messages that have been filtered out.
311 sub reset_local_duplicates
()
313 return _reset_duplicates
%_local_duplicate_messages;
316 =item C<reset_global_duplicates ()>
318 Reset local duplicate messages (see C<US_GLOBAL>), and
319 return the number of messages that have been filtered out.
323 sub reset_global_duplicates
()
325 return _reset_duplicates
%_global_duplicate_messages;
328 sub _merge_options
(\
%%)
330 my ($hash, %options) = @_;
333 foreach (keys %options)
335 if (exists $hash->{$_})
337 $hash->{$_} = $options{$_}
341 confess
"unknown option `$_'";
344 if ($hash->{'ordered'})
346 confess
"fatal messages cannot be ordered"
347 if $hash->{'type'} eq 'fatal';
348 confess
"backtrace cannot be output on ordered messages"
349 if $hash->{'backtrace'};
353 =item C<register_channel ($name, [%options])>
355 Declare channel C<$name>, and override the default options
356 with those listed in C<%options>.
360 sub register_channel
($;%)
362 my ($name, %options) = @_;
363 my %channel_opts = %_default_options;
364 _merge_options
%channel_opts, %options;
365 $channels{$name} = \
%channel_opts;
368 =item C<exists_channel ($name)>
370 Returns true iff channel C<$name> has been registered.
374 sub exists_channel
($)
377 return exists $channels{$name};
380 =item C<channel_type ($name)>
382 Returns the type of channel C<$name> if it has been registered.
383 Returns the empty string otherwise.
390 return $channels{$name}{'type'} if exists_channel
$name;
394 # _format_sub_message ($LEADER, $MESSAGE)
395 # ---------------------------------------
396 # Split $MESSAGE at new lines and add $LEADER to each line.
397 sub _format_sub_message
($$)
399 my ($leader, $message) = @_;
400 return $leader . join ("\n" . $leader, split ("\n", $message)) . "\n";
403 # _format_message ($LOCATION, $MESSAGE, %OPTIONS)
404 # -----------------------------------------------
405 # Format the message. Return a string ready to print.
406 sub _format_message
($$%)
408 my ($location, $message, %opts) = @_;
412 # If $LOCATION is a reference, assume it's an instance of the
413 # Autom4te::Location class and display contexts.
414 my $loc = $location->get || $me;
415 $msg = _format_sub_message
("$loc: ", $opts{'header'}
416 . $message . $opts{'footer'});
417 for my $pair ($location->get_contexts)
419 $msg .= _format_sub_message
($pair->[0] . ": ", $pair->[1]);
425 $msg = _format_sub_message
("$location: ", $opts{'header'}
426 . $message . $opts{'footer'});
431 # _enqueue ($QUEUE, $KEY, $UNIQ_SCOPE, $TO_FILTER, $MSG, $FILE)
432 # ------------------------------------------------------------
433 # Push message on a queue, to be processed by another thread.
434 sub _enqueue
($$$$$$)
436 my ($queue, $key, $uniq_scope, $to_filter, $msg, $file) = @_;
437 $queue->enqueue ($key, $msg, $to_filter, $uniq_scope);
438 confess
"message queuing works only for STDERR"
439 if $file ne \
*STDERR
;
444 # Pop a message from a queue, and print, similarly to how
445 # _print_message would do it. Return 0 if the queue is
446 # empty. Note that the key has already been dequeued.
450 my $msg = $queue->dequeue || return 0;
451 my $to_filter = $queue->dequeue;
452 my $uniq_scope = $queue->dequeue;
455 if ($to_filter ne '')
457 # Do we want local or global uniqueness?
459 if ($uniq_scope == US_LOCAL
)
461 $dups = \
%_local_duplicate_messages;
463 elsif ($uniq_scope == US_GLOBAL
)
465 $dups = \
%_global_duplicate_messages;
469 confess
"unknown value for uniq_scope: " . $uniq_scope;
472 # Update the hash of messages.
473 if (exists $dups->{$to_filter})
475 ++$dups->{$to_filter};
480 $dups->{$to_filter} = 0;
488 # Store partial messages here. (See the 'partial' option.)
489 use vars qw
($partial);
492 # _print_message ($LOCATION, $MESSAGE, %OPTIONS)
493 # ----------------------------------------------
494 # Format the message, check duplicates, and print it.
495 sub _print_message
($$%)
497 my ($location, $message, %opts) = @_;
499 return 0 if ($opts{'silent'});
501 my $msg = _format_message
($location, $message, %opts);
502 if ($opts{'partial'})
504 # Incomplete message. Store, don't print.
510 # Prefix with any partial message send so far.
511 $msg = $partial . $msg;
515 # Check for duplicate message if requested.
517 if ($opts{'uniq_part'} ne UP_NONE
)
519 # Which part of the error should we match?
520 if ($opts{'uniq_part'} eq UP_TEXT
)
522 $to_filter = $message;
524 elsif ($opts{'uniq_part'} eq UP_LOC_TEXT
)
530 $to_filter = $opts{'uniq_part'};
533 # Do we want local or global uniqueness?
535 if ($opts{'uniq_scope'} == US_LOCAL
)
537 $dups = \
%_local_duplicate_messages;
539 elsif ($opts{'uniq_scope'} == US_GLOBAL
)
541 $dups = \
%_global_duplicate_messages;
545 confess
"unknown value for uniq_scope: " . $opts{'uniq_scope'};
548 # Update the hash of messages.
549 if (exists $dups->{$to_filter})
551 ++$dups->{$to_filter};
556 $dups->{$to_filter} = 0;
559 my $file = $opts{'file'};
560 if ($opts{'ordered'} && $opts{'queue'})
562 _enqueue
($opts{'queue'}, $opts{'queue_key'}, $opts{'uniq_scope'},
563 $to_filter, $msg, $file);
572 =item C<msg ($channel, $location, $message, [%options])>
574 Emit a message on C<$channel>, overriding some options of the channel with
575 those specified in C<%options>. Obviously C<$channel> must have been
576 registered with C<register_channel>.
578 C<$message> is the text of the message, and C<$location> is a location
579 associated to the message.
581 For instance to complain about some unused variable C<mumble>
582 declared at line 10 in F<foo.c>, one could do:
584 msg 'unused', 'foo.c:10', "unused variable `mumble'";
586 If channel C<unused> is not silent (and if this message is not a duplicate),
587 the following would be output:
589 foo.c:10: unused variable `mumble'
591 C<$location> can also be an instance of C<Autom4te::Location>. In this
592 case, the stack of contexts will be displayed in addition.
594 If C<$message> contains newline characters, C<$location> is prepended
595 to each line. For instance,
597 msg 'error', 'somewhere', "1st line\n2nd line";
604 If C<$location> is an empty string, it is replaced by the name of the
605 program. Actually, if you don't use C<%options>, you can even
606 elide the empty C<$location>. Thus
608 msg 'fatal', '', 'fatal error';
609 msg 'fatal', 'fatal error';
613 progname: fatal error
618 use vars qw
(@backlog %buffering);
620 # See buffer_messages() and flush_messages() below.
621 %buffering = (); # The map of channel types to buffer.
622 @backlog = (); # The buffer of messages.
626 my ($channel, $location, $message, %options) = @_;
628 if (! defined $message)
630 $message = $location;
634 confess
"unknown channel $channel" unless exists $channels{$channel};
636 my %opts = %{$channels{$channel}};
637 _merge_options
(%opts, %options);
639 if (exists $buffering{$opts{'type'}})
641 push @backlog, [$channel, $location->clone, $message, %options];
645 # Print the message if needed.
646 if (_print_message
($location, $message, %opts))
648 # Adjust exit status.
649 if ($opts{'type'} eq 'error'
650 || $opts{'type'} eq 'fatal'
651 || ($opts{'type'} eq 'warning' && $warnings_are_errors))
653 my $es = $opts{'exit_code'};
654 $exit_code = $es if $es > $exit_code;
657 # Die on fatal messages.
658 confess
if $opts{'backtrace'};
659 if ($opts{'type'} eq 'fatal')
661 # flush messages explicitly here, needed in worker threads.
669 =item C<setup_channel ($channel, %options)>
671 Override the options of C<$channel> with those specified by C<%options>.
675 sub setup_channel
($%)
677 my ($name, %opts) = @_;
678 confess
"channel $name doesn't exist" unless exists $channels{$name};
679 _merge_options
%{$channels{$name}}, %opts;
682 =item C<setup_channel_type ($type, %options)>
684 Override the options of any channel of type C<$type>
685 with those specified by C<%options>.
689 sub setup_channel_type
($%)
691 my ($type, %opts) = @_;
692 foreach my $channel (keys %channels)
694 setup_channel
$channel, %opts
695 if $channels{$channel}{'type'} eq $type;
699 =item C<dup_channel_setup ()>, C<drop_channel_setup ()>
701 Sometimes it is necessary to make temporary modifications to channels.
702 For instance one may want to disable a warning while processing a
703 particular file, and then restore the initial setup. These two
704 functions make it easy: C<dup_channel_setup ()> saves a copy of the
705 current configuration for later restoration by
706 C<drop_channel_setup ()>.
708 You can think of this as a stack of configurations whose first entry
709 is the active one. C<dup_channel_setup ()> duplicates the first
710 entry, while C<drop_channel_setup ()> just deletes it.
714 use vars qw
(@_saved_channels);
715 @_saved_channels = ();
717 sub dup_channel_setup
()
720 foreach my $k1 (keys %channels)
722 $channels_copy{$k1} = {%{$channels{$k1}}};
724 push @_saved_channels, \
%channels_copy;
727 sub drop_channel_setup
()
729 my $saved = pop @_saved_channels;
733 =item C<buffer_messages (@types)>, C<flush_messages ()>
735 By default, when C<msg> is called, messages are processed immediately.
737 Sometimes it is necessary to delay the output of messages.
738 For instance you might want to make diagnostics before
739 channels have been completely configured.
741 After C<buffer_messages(@types)> has been called, messages sent with
742 C<msg> to a channel whose type is listed in C<@types> will be stored in a
743 list for later processing.
745 This backlog of messages is processed when C<flush_messages> is
746 called, with the current channel options (not the options in effect,
747 at the time of C<msg>). So for instance, if some channel was silenced
748 in the meantime, messages to this channel will not be printed.
750 C<flush_messages> cancels the effect of C<buffer_messages>. Following
751 calls to C<msg> are processed immediately as usual.
755 sub buffer_messages
(@
)
757 foreach my $type (@_)
759 $buffering{$type} = 1;
763 sub flush_messages
()
766 foreach my $args (@backlog)
773 =item C<setup_channel_queue ($queue, $key)>
775 Set the queue to fill for each channel that is ordered,
776 and the key to use for serialization.
779 sub setup_channel_queue
($$)
781 my ($queue, $key) = @_;
782 foreach my $channel (keys %channels)
784 setup_channel
$channel, queue
=> $queue, queue_key
=> $key
785 if $channels{$channel}{'ordered'};
789 =item C<pop_channel_queue ($queue)>
791 pop a message off the $queue; the key has already been popped.
794 sub pop_channel_queue
($)
797 return _dequeue
($queue);
804 L<Autom4te::Location>
808 Written by Alexandre Duret-Lutz E<lt>F<adl@gnu.org>E<gt>.
814 ### Setup "GNU" style for perl-mode and cperl-mode.
816 ## perl-indent-level: 2
817 ## perl-continued-statement-offset: 2
818 ## perl-continued-brace-offset: 0
819 ## perl-brace-offset: 0
820 ## perl-brace-imaginary-offset: 0
821 ## perl-label-offset: -2
822 ## cperl-indent-level: 2
823 ## cperl-brace-offset: 0
824 ## cperl-continued-brace-offset: 0
825 ## cperl-label-offset: -2
826 ## cperl-extra-newline-before-brace: t
827 ## cperl-merge-trailing-else: nil
828 ## cperl-continued-statement-offset: 2