Improve INSTALL wording.
[autoconf.git] / lib / Autom4te / Channels.pm
blob1309d204ad2a6ec48fc87ce4745d5f11a49c5484
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)
6 # any later version.
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
16 # 02110-1301, USA.
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;
25 =head1 NAME
27 Autom4te::Channels - support functions for error and warning management
29 =head1 SYNOPSIS
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.
59 exit $exit_code;
61 =head1 DESCRIPTION
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.
69 =cut
71 use 5.005;
72 use strict;
73 use Exporter;
74 use Carp;
75 use File::Basename;
77 use vars qw (@ISA @EXPORT %channels $me);
79 @ISA = qw (Exporter);
80 @EXPORT = qw ($exit_code $warnings_are_errors
81 &reset_local_duplicates &reset_global_duplicates
82 &register_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
87 US_GLOBAL US_LOCAL
88 UP_NONE UP_TEXT UP_LOC_TEXT);
90 $me = basename $0;
92 =head2 Global Variables
94 =over 4
96 =item C<$exit_code>
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.
101 =cut
103 use vars qw ($exit_code);
104 $exit_code = 0;
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>).
111 =cut
113 use vars qw ($warnings_are_errors);
114 $warnings_are_errors = 0;
116 =back
118 =head2 Constants
120 =over 4
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
130 should be output.
132 =cut
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.)
147 =cut
149 # possible values for uniq_scope
150 use constant US_LOCAL => 0;
151 use constant US_GLOBAL => 1;
153 =back
155 =head2 Options
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:
161 =over
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
189 for ordered output.
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>
195 constants above.
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
226 option.
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';
235 will result in
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
242 filtered out.
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
254 be ignored.
256 =back
258 =cut
260 use vars qw (%_default_options %_global_duplicate_messages
261 %_local_duplicate_messages);
263 # Default options for a channel.
264 %_default_options =
266 type => 'warning',
267 exit_code => 1,
268 file => \*STDERR,
269 silent => 0,
270 ordered => 1,
271 queue => 0,
272 queue_key => undef,
273 uniq_scope => US_LOCAL,
274 uniq_part => UP_LOC_TEXT,
275 header => '',
276 footer => '',
277 backtrace => 0,
278 partial => 0,
281 # Filled with output messages as keys, to detect duplicates.
282 # The value associated with each key is the number of occurrences
283 # filtered out.
284 %_local_duplicate_messages = ();
285 %_global_duplicate_messages = ();
287 sub _reset_duplicates (\%)
289 my ($ref) = @_;
290 my $dup = 0;
291 foreach my $k (keys %$ref)
293 $dup += $ref->{$k};
295 %$ref = ();
296 return $dup;
300 =head2 Functions
302 =over 4
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.
309 =cut
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.
321 =cut
323 sub reset_global_duplicates ()
325 return _reset_duplicates %_global_duplicate_messages;
328 sub _merge_options (\%%)
330 my ($hash, %options) = @_;
331 local $_;
333 foreach (keys %options)
335 if (exists $hash->{$_})
337 $hash->{$_} = $options{$_}
339 else
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>.
358 =cut
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.
372 =cut
374 sub exists_channel ($)
376 my ($name) = @_;
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.
385 =cut
387 sub channel_type ($)
389 my ($name) = @_;
390 return $channels{$name}{'type'} if exists_channel $name;
391 return '';
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) = @_;
409 my $msg = '';
410 if (ref $location)
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]);
422 else
424 $location ||= $me;
425 $msg = _format_sub_message ("$location: ", $opts{'header'}
426 . $message . $opts{'footer'});
428 return $msg;
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;
442 # _dequeue ($QUEUE)
443 # -----------------
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.
447 sub _dequeue ($)
449 my ($queue) = @_;
450 my $msg = $queue->dequeue || return 0;
451 my $to_filter = $queue->dequeue;
452 my $uniq_scope = $queue->dequeue;
453 my $file = \*STDERR;
455 if ($to_filter ne '')
457 # Do we want local or global uniqueness?
458 my $dups;
459 if ($uniq_scope == US_LOCAL)
461 $dups = \%_local_duplicate_messages;
463 elsif ($uniq_scope == US_GLOBAL)
465 $dups = \%_global_duplicate_messages;
467 else
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};
476 return 1;
478 else
480 $dups->{$to_filter} = 0;
483 print $file $msg;
484 return 1;
488 # Store partial messages here. (See the 'partial' option.)
489 use vars qw ($partial);
490 $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.
505 $partial .= $msg;
506 return;
508 else
510 # Prefix with any partial message send so far.
511 $msg = $partial . $msg;
512 $partial = '';
515 # Check for duplicate message if requested.
516 my $to_filter;
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)
526 $to_filter = $msg;
528 else
530 $to_filter = $opts{'uniq_part'};
533 # Do we want local or global uniqueness?
534 my $dups;
535 if ($opts{'uniq_scope'} == US_LOCAL)
537 $dups = \%_local_duplicate_messages;
539 elsif ($opts{'uniq_scope'} == US_GLOBAL)
541 $dups = \%_global_duplicate_messages;
543 else
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};
552 return 0;
554 else
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);
565 else
567 print $file $msg;
569 return 1;
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";
599 becomes
601 somewhere: 1st line
602 somewhere: 2nd 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';
611 both print
613 progname: fatal error
615 =cut
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.
624 sub msg ($$;$%)
626 my ($channel, $location, $message, %options) = @_;
628 if (! defined $message)
630 $message = $location;
631 $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];
642 return;
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.
662 STDERR->flush;
663 exit $exit_code;
669 =item C<setup_channel ($channel, %options)>
671 Override the options of C<$channel> with those specified by C<%options>.
673 =cut
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>.
687 =cut
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.
712 =cut
714 use vars qw (@_saved_channels);
715 @_saved_channels = ();
717 sub dup_channel_setup ()
719 my %channels_copy;
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;
730 %channels = %$saved;
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.
753 =cut
755 sub buffer_messages (@)
757 foreach my $type (@_)
759 $buffering{$type} = 1;
763 sub flush_messages ()
765 %buffering = ();
766 foreach my $args (@backlog)
768 &msg (@$args);
770 @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.
778 =cut
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.
793 =cut
794 sub pop_channel_queue ($)
796 my ($queue) = @_;
797 return _dequeue ($queue);
800 =back
802 =head1 SEE ALSO
804 L<Autom4te::Location>
806 =head1 HISTORY
808 Written by Alexandre Duret-Lutz E<lt>F<adl@gnu.org>E<gt>.
810 =cut
814 ### Setup "GNU" style for perl-mode and cperl-mode.
815 ## Local Variables:
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
829 ## End: