📄 channels.pm
字号:
# Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.# This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2, or (at your option)# any later version.# This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.# You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA# 02110-1301, USA.################################################################ The main copy of this file is in Automake's CVS repository. ## Updates should be sent to automake-patches@gnu.org. ################################################################package Autom4te::Channels;=head1 NAMEAutom4te::Channels - support functions for error and warning management=head1 SYNOPSIS use Autom4te::Channels; # Register a channel to output warnings about unused variables. register_channel 'unused', type => 'warning'; # Register a channel for system errors. register_channel 'system', type => 'error', exit_code => 4; # Output a message on channel 'unused'. msg 'unused', "$file:$line", "unused variable `$var'"; # Make the 'unused' channel silent. setup_channel 'unused', silent => 1; # Turn on all channels of type 'warning'. setup_channel_type 'warning', silent => 0; # Treat all warnings as errors. $warnings_are_errors = 1; # Exit with the greatest exit code encountered so far. exit $exit_code;=head1 DESCRIPTIONThis perl module provides support functions for handling diagnosticchannels in programs. Channels can be registered to convey fatal,error, warning, or debug messages. Each channel has various options(e.g. is the channel silent, should duplicate messages be removed,etc.) that can also be overridden on a per-message basis.=cutuse 5.005;use strict;use Exporter;use Carp;use File::Basename;use vars qw (@ISA @EXPORT %channels $me);@ISA = qw (Exporter);@EXPORT = qw ($exit_code $warnings_are_errors &reset_local_duplicates &reset_global_duplicates ®ister_channel &msg &exists_channel &channel_type &setup_channel &setup_channel_type &dup_channel_setup &drop_channel_setup &buffer_messages &flush_messages US_GLOBAL US_LOCAL UP_NONE UP_TEXT UP_LOC_TEXT);$me = basename $0;=head2 Global Variables=over 4=item C<$exit_code>The greatest exit code seen so far. C<$exit_code> is updated fromthe C<exit_code> options of C<fatal> and C<error> channels.=cutuse vars qw ($exit_code);$exit_code = 0;=item C<$warnings_are_errors>Set this variable to 1 if warning messages should be treated aserrors (i.e. if they should update C<$exit_code>).=cutuse vars qw ($warnings_are_errors);$warnings_are_errors = 0;=back=head2 Constants=over 4=item C<UP_NONE>, C<UP_TEXT>, C<UP_LOC_TEXT>Possible values for the C<uniq_part> options. This selects the partof the message that should be considered when filtering out duplicates.If C<UP_LOC_TEXT> is used, the location and the explanation messageare used for filtering. If C<UP_TEXT> is used, only the explanationmessage is used (so the same message will be filtered out if it appearsat different locations). C<UP_NONE> means that duplicate messagesshould be output.=cutuse constant UP_NONE => 0;use constant UP_TEXT => 1;use constant UP_LOC_TEXT => 2;=item C<US_LOCAL>, C<US_GLOBAL>Possible values for the C<uniq_scope> options.Use C<US_GLOBAL> for error messages that should be printed onlyonce during the execution of the program, C<US_LOCAL> for message thatshould be printed only once per file. (Actually, C<Channels> does notdo this now when files are changed, it relies on you callingC<reset_local_duplicates> when this happens.)=cut# possible values for uniq_scopeuse constant US_LOCAL => 0;use constant US_GLOBAL => 1;=back=head2 OptionsChannels accept the options described below. These options can bepassed as a hash to the C<register_channel>, C<setup_channel>, and C<msg>functions. The possible keys, with their default value are:=over=item C<type =E<gt> 'warning'>The type of the channel. One of C<'debug'>, C<'warning'>, C<'error'>, orC<'fatal'>. Fatal messages abort the program when they are output.Error messages update the exit status. Debug and warning messages areharmless, except that warnings can be treated as errors ofC<$warnings_are_errors> is set.=item C<exit_code =E<gt> 1>The value to update C<$exit_code> with when a fatal or error messageis emitted. C<$exit_code> is also updated for warnings outputwhen @<$warnings_are_errors> is set.=item C<file =E<gt> \*STDERR>The file where the error should be output.=item C<silent =E<gt> 0>Whether the channel should be silent. Use this do disable acategory of warning, for instance.=item C<uniq_part =E<gt> UP_LOC_TEXT>The part of the message subject to duplicate filtering. See thedocumentation for the C<UP_NONE>, C<UP_TEXT>, and C<UP_LOC_TEXT>constants above.C<uniq_part> can also be set to an arbitrary string that will be usedinstead of the message when considering duplicates.=item C<uniq_scope =E<gt> US_LOCAL>The scope of duplicate filtering. See the documentation for theC<US_LOCAL>, and C<US_GLOBAL> constants above.=item C<header =E<gt> ''>A string to prepend to each message emitted through this channel.=item C<footer =E<gt> ''>A string to append to each message emitted through this channel.=item C<backtrace =E<gt> 0>Die with a stack backtrace after displaying the message.=item C<partial =E<gt> 0>When set, indicates a partial message that shouldbe output along with the next message with C<partial> unset.Several partial messages can be stacked this way.Duplicate filtering will apply to the I<global> message resulting fromall I<partial> messages, using the options from the last (non-partial)message. Linking associated messages is the main reason to use thisoption.For instance the following messages msg 'channel', 'foo:2', 'redefinition of A ...'; msg 'channel', 'foo:1', '... A previously defined here'; msg 'channel', 'foo:3', 'redefinition of A ...'; msg 'channel', 'foo:1', '... A previously defined here';will result in foo:2: redefinition of A ... foo:1: ... A previously defined here foo:3: redefinition of A ...where the duplicate "I<... A previously defined here>" has beenfiltered out.Linking these messages using C<partial> as follows will prevent thefourth message to disappear. msg 'channel', 'foo:2', 'redefinition of A ...', partial => 1; msg 'channel', 'foo:1', '... A previously defined here'; msg 'channel', 'foo:3', 'redefinition of A ...', partial => 1; msg 'channel', 'foo:1', '... A previously defined here';Note that because the stack of C<partial> messages is printed with thefirst non-C<partial> message, most options of C<partial> messages willbe ignored.=back=cutuse vars qw (%_default_options %_global_duplicate_messages %_local_duplicate_messages);# Default options for a channel.%_default_options = ( type => 'warning', exit_code => 1, file => \*STDERR, silent => 0, uniq_scope => US_LOCAL, uniq_part => UP_LOC_TEXT, header => '', footer => '', backtrace => 0, partial => 0, );# Filled with output messages as keys, to detect duplicates.# The value associated with each key is the number of occurrences# filtered out.%_local_duplicate_messages = ();%_global_duplicate_messages = ();sub _reset_duplicates (\%){ my ($ref) = @_; my $dup = 0; foreach my $k (keys %$ref) { $dup += $ref->{$k}; } %$ref = (); return $dup;}=head2 Functions=over 4=item C<reset_local_duplicates ()>Reset local duplicate messages (see C<US_LOCAL>), andreturn the number of messages that have been filtered out.=cutsub reset_local_duplicates (){ return _reset_duplicates %_local_duplicate_messages;}=item C<reset_global_duplicates ()>Reset local duplicate messages (see C<US_GLOBAL>), andreturn the number of messages that have been filtered out.=cutsub reset_global_duplicates (){ return _reset_duplicates %_global_duplicate_messages;}sub _merge_options (\%%){ my ($hash, %options) = @_; local $_; foreach (keys %options) { if (exists $hash->{$_}) { $hash->{$_} = $options{$_} } else { confess "unknown option `$_'"; } }}=item C<register_channel ($name, [%options])>Declare channel C<$name>, and override the default optionswith those listed in C<%options>.=cutsub register_channel ($;%){ my ($name, %options) = @_; my %channel_opts = %_default_options; _merge_options %channel_opts, %options; $channels{$name} = \%channel_opts;}=item C<exists_channel ($name)>Returns true iff channel C<$name> has been registered.=cutsub exists_channel ($){ my ($name) = @_; return exists $channels{$name};}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -