1# Copyright (C) 2002-2003, 2006, 2008-2012 Free Software Foundation, 2# Inc. 3 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 3 of the License, or 7# (at your option) any later version. 8 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. 13 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/>. 16 17package Autom4te::ChannelDefs; 18 19use Autom4te::Channels; 20 21=head1 NAME 22 23Autom4te::ChannelDefs - channel definitions for Automake and helper functions 24 25=head1 SYNOPSIS 26 27 use Autom4te::ChannelDefs; 28 29 print Autom4te::ChannelDefs::usage (), "\n"; 30 prog_error ($MESSAGE, [%OPTIONS]); 31 error ($WHERE, $MESSAGE, [%OPTIONS]); 32 error ($MESSAGE); 33 fatal ($WHERE, $MESSAGE, [%OPTIONS]); 34 fatal ($MESSAGE); 35 verb ($MESSAGE, [%OPTIONS]); 36 switch_warning ($CATEGORY); 37 parse_WARNINGS (); 38 parse_warnings ($OPTION, @ARGUMENT); 39 Autom4te::ChannelDefs::set_strictness ($STRICTNESS_NAME); 40 41=head1 DESCRIPTION 42 43This package defines channels that can be used in Automake to 44output diagnostics and other messages (via C<msg()>). It also defines 45some helper function to enable or disable these channels, and some 46shorthand function to output on specific channels. 47 48=cut 49 50use 5.006; 51use strict; 52use Exporter; 53 54use vars qw (@ISA @EXPORT); 55 56@ISA = qw (Exporter); 57@EXPORT = qw (&prog_error &error &fatal &verb 58 &switch_warning &parse_WARNINGS &parse_warnings); 59 60=head2 CHANNELS 61 62The following channels can be used as the first argument of 63C<Autom4te::Channel::msg>. For some of them we list a shorthand 64function that makes the code more readable. 65 66=over 4 67 68=item C<fatal> 69 70Fatal errors. Use C<&fatal> to send messages over this channel. 71 72=item C<error> 73 74Common errors. Use C<&error> to send messages over this channel. 75 76=item C<error-gnu> 77 78Errors related to GNU Standards. 79 80=item C<error-gnu/warn> 81 82Errors related to GNU Standards that should be warnings in "foreign" mode. 83 84=item C<error-gnits> 85 86Errors related to GNITS Standards (silent by default). 87 88=item C<automake> 89 90Internal errors. Use C<&prog_error> to send messages over this channel. 91 92=item C<cross> 93 94Constructs compromising the cross-compilation of the package. 95 96=item C<gnu> 97 98Warnings related to GNU Coding Standards. 99 100=item C<obsolete> 101 102Warnings about obsolete features (silent by default). 103 104=item C<override> 105 106Warnings about user redefinitions of Automake rules or 107variables (silent by default). 108 109=item C<portability> 110 111Warnings about non-portable constructs. 112 113=item C<syntax> 114 115Warnings about weird syntax, unused variables, typos ... 116 117=item C<unsupported> 118 119Warnings about unsupported (or mis-supported) features. 120 121=item C<verb> 122 123Messages output in C<--verbose> mode. Use C<&verb> to send such messages. 124 125=item C<note> 126 127Informative messages. 128 129=back 130 131=cut 132 133# Initialize our list of error/warning channels. 134# Do not forget to update &usage and the manual 135# if you add or change a warning channel. 136 137register_channel 'fatal', type => 'fatal', ordered => 0; 138register_channel 'error', type => 'error'; 139register_channel 'error-gnu', type => 'error'; 140register_channel 'error-gnu/warn', type => 'error'; 141register_channel 'error-gnits', type => 'error', silent => 1; 142register_channel 'automake', type => 'fatal', backtrace => 1, 143 header => ("####################\n" . 144 "## Internal Error ##\n" . 145 "####################\n"), 146 footer => "\nPlease contact <bug-automake\@gnu.org>.", 147 ordered => 0; 148 149register_channel 'cross', type => 'warning', silent => 1; 150register_channel 'gnu', type => 'warning'; 151register_channel 'obsolete', type => 'warning', silent => 1; 152register_channel 'override', type => 'warning', silent => 1; 153register_channel 'portability', type => 'warning', silent => 1; 154register_channel 'syntax', type => 'warning'; 155register_channel 'unsupported', type => 'warning'; 156 157register_channel 'verb', type => 'debug', silent => 1, ordered => 0; 158register_channel 'note', type => 'debug', silent => 0; 159 160=head2 FUNCTIONS 161 162=over 4 163 164=item C<usage ()> 165 166Return the warning category descriptions. 167 168=cut 169 170sub usage () 171{ 172 return "Warning categories include: 173 `cross' cross compilation issues 174 `gnu' GNU coding standards (default in gnu and gnits modes) 175 `obsolete' obsolete features or constructions 176 `override' user redefinitions of Automake rules or variables 177 `portability' portability issues (default in gnu and gnits modes) 178 `syntax' dubious syntactic constructs (default) 179 `unsupported' unsupported or incomplete features (default) 180 `all' all the warnings 181 `no-CATEGORY' turn off warnings in CATEGORY 182 `none' turn off all the warnings 183 `error' treat warnings as errors"; 184} 185 186=item C<prog_error ($MESSAGE, [%OPTIONS])> 187 188Signal a programming error (on channel C<automake>), 189display C<$MESSAGE>, and exit 1. 190 191=cut 192 193sub prog_error ($;%) 194{ 195 my ($msg, %opts) = @_; 196 msg 'automake', '', $msg, %opts; 197} 198 199=item C<error ($WHERE, $MESSAGE, [%OPTIONS])> 200 201=item C<error ($MESSAGE)> 202 203Uncategorized errors. 204 205=cut 206 207sub error ($;$%) 208{ 209 my ($where, $msg, %opts) = @_; 210 msg ('error', $where, $msg, %opts); 211} 212 213=item C<fatal ($WHERE, $MESSAGE, [%OPTIONS])> 214 215=item C<fatal ($MESSAGE)> 216 217Fatal errors. 218 219=cut 220 221sub fatal ($;$%) 222{ 223 my ($where, $msg, %opts) = @_; 224 msg ('fatal', $where, $msg, %opts); 225} 226 227=item C<verb ($MESSAGE, [%OPTIONS])> 228 229C<--verbose> messages. 230 231=cut 232 233sub verb ($;%) 234{ 235 my ($msg, %opts) = @_; 236 msg 'verb', '', $msg, %opts; 237} 238 239=item C<switch_warning ($CATEGORY)> 240 241If C<$CATEGORY> is C<mumble>, turn on channel C<mumble>. 242If it is C<no-mumble>, turn C<mumble> off. 243Else handle C<all> and C<none> for completeness. 244 245=cut 246 247sub switch_warning ($) 248{ 249 my ($cat) = @_; 250 my $has_no = 0; 251 252 if ($cat =~ /^no-(.*)$/) 253 { 254 $cat = $1; 255 $has_no = 1; 256 } 257 258 if ($cat eq 'all') 259 { 260 setup_channel_type 'warning', silent => $has_no; 261 } 262 elsif ($cat eq 'none') 263 { 264 setup_channel_type 'warning', silent => ! $has_no; 265 } 266 elsif ($cat eq 'error') 267 { 268 $warnings_are_errors = ! $has_no; 269 # Set exit code if Perl warns about something 270 # (like uninitialized variables). 271 $SIG{"__WARN__"} = 272 $has_no ? 'DEFAULT' : sub { print STDERR @_; $exit_code = 1; }; 273 } 274 elsif (channel_type ($cat) eq 'warning') 275 { 276 setup_channel $cat, silent => $has_no; 277 } 278 else 279 { 280 return 1; 281 } 282 return 0; 283} 284 285=item C<parse_WARNINGS ()> 286 287Parse the WARNINGS environment variable. 288 289=cut 290 291sub parse_WARNINGS () 292{ 293 if (exists $ENV{'WARNINGS'}) 294 { 295 # Ignore unknown categories. This is required because WARNINGS 296 # should be honored by many tools. 297 switch_warning $_ foreach (split (',', $ENV{'WARNINGS'})); 298 } 299} 300 301=item C<parse_warnings ($OPTION, @ARGUMENT)> 302 303Parse the argument of C<--warning=CATEGORY> or C<-WCATEGORY>. 304 305C<$OPTIONS> is C<"--warning"> or C<"-W">, C<@ARGUMENT> is a list of 306C<CATEGORY>. 307 308This can be used as an argument to C<Getopt>. 309 310=cut 311 312sub parse_warnings ($@) 313{ 314 my ($opt, @categories) = @_; 315 316 foreach my $cat (map { split ',' } @categories) 317 { 318 msg 'unsupported', "unknown warning category `$cat'" 319 if switch_warning $cat; 320 } 321} 322 323=item C<set_strictness ($STRICTNESS_NAME)> 324 325Configure channels for strictness C<$STRICTNESS_NAME>. 326 327=cut 328 329sub set_strictness ($) 330{ 331 my ($name) = @_; 332 333 if ($name eq 'gnu') 334 { 335 setup_channel 'error-gnu', silent => 0; 336 setup_channel 'error-gnu/warn', silent => 0, type => 'error'; 337 setup_channel 'error-gnits', silent => 1; 338 setup_channel 'portability', silent => 0; 339 setup_channel 'gnu', silent => 0; 340 } 341 elsif ($name eq 'gnits') 342 { 343 setup_channel 'error-gnu', silent => 0; 344 setup_channel 'error-gnu/warn', silent => 0, type => 'error'; 345 setup_channel 'error-gnits', silent => 0; 346 setup_channel 'portability', silent => 0; 347 setup_channel 'gnu', silent => 0; 348 } 349 elsif ($name eq 'foreign') 350 { 351 setup_channel 'error-gnu', silent => 1; 352 setup_channel 'error-gnu/warn', silent => 0, type => 'warning'; 353 setup_channel 'error-gnits', silent => 1; 354 setup_channel 'portability', silent => 1; 355 setup_channel 'gnu', silent => 1; 356 } 357 else 358 { 359 prog_error "level `$name' not recognized\n"; 360 } 361} 362 363=back 364 365=head1 SEE ALSO 366 367L<Autom4te::Channels> 368 369=head1 HISTORY 370 371Written by Alexandre Duret-Lutz E<lt>F<adl@gnu.org>E<gt>. 372 373=cut 374 375### Setup "GNU" style for perl-mode and cperl-mode. 376## Local Variables: 377## perl-indent-level: 2 378## perl-continued-statement-offset: 2 379## perl-continued-brace-offset: 0 380## perl-brace-offset: 0 381## perl-brace-imaginary-offset: 0 382## perl-label-offset: -2 383## cperl-indent-level: 2 384## cperl-brace-offset: 0 385## cperl-continued-brace-offset: 0 386## cperl-label-offset: -2 387## cperl-extra-newline-before-brace: t 388## cperl-merge-trailing-else: nil 389## cperl-continued-statement-offset: 2 390## End: 391