File Coverage

blib/lib/auto/share/dist/Alien-autoconf/share/autoconf/Autom4te/ChannelDefs.pm
Criterion Covered Total %
statement 19 104 18.2
branch 1 48 2.0
condition 0 5 0.0
subroutine 8 18 44.4
pod 10 10 100.0
total 38 185 20.5


line stmt bran cond sub pod time code
1             # Copyright (C) 2002-2023 Free Software Foundation, Inc.
2              
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.
7              
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.
12              
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16             package Autom4te::ChannelDefs;
17              
18             =head1 NAME
19              
20             Autom4te::ChannelDefs - channel definitions for Automake and helper functions
21              
22             =head1 SYNOPSIS
23              
24             use Autom4te::ChannelDefs;
25              
26             print Autom4te::ChannelDefs::usage (), "\n";
27             prog_error ($MESSAGE, [%OPTIONS]);
28             error ($WHERE, $MESSAGE, [%OPTIONS]);
29             error ($MESSAGE);
30             fatal ($WHERE, $MESSAGE, [%OPTIONS]);
31             fatal ($MESSAGE);
32             verb ($MESSAGE, [%OPTIONS]);
33             switch_warning ($CATEGORY);
34             parse_WARNINGS ();
35             parse_warnings ($OPTION, @ARGUMENT);
36             Autom4te::ChannelDefs::set_strictness ($STRICTNESS_NAME);
37              
38             =head1 DESCRIPTION
39              
40             This package defines channels that can be used in Automake to
41             output diagnostics and other messages (via C). It also defines
42             some helper function to enable or disable these channels, and some
43             shorthand function to output on specific channels.
44              
45             =cut
46              
47 7     7   140 use 5.006;
  7         28  
48 7     7   45 use strict;
  7         30  
  7         245  
49 7     7   60 use warnings FATAL => 'all';
  7         27  
  7         490  
50              
51 7     7   43 use Exporter;
  7         16  
  7         357  
52              
53 7     7   4681 use Autom4te::Channels;
  7         24  
  7         1718  
54 7     7   4550 use Autom4te::Config;
  7         18  
  7         959  
55             BEGIN
56             {
57 7 50   7   12739 if ($perl_threads)
58             {
59 0         0 require threads;
60 0         0 import threads;
61             }
62             }
63              
64             our @ISA = qw (Exporter);
65             our @EXPORT = qw (&prog_error &error &fatal &verb
66             &switch_warning &parse_WARNINGS &parse_warnings
67             &merge_WARNINGS);
68              
69             =head2 CHANNELS
70              
71             The following channels can be used as the first argument of
72             C. For some of them we list a shorthand
73             function that makes the code more readable.
74              
75             =over 4
76              
77             =item C
78              
79             Fatal errors. Use C<&fatal> to send messages over this channel.
80              
81             =item C
82              
83             Common errors. Use C<&error> to send messages over this channel.
84              
85             =item C
86              
87             Errors related to GNU Standards.
88              
89             =item C
90              
91             Errors related to GNU Standards that should be warnings in 'foreign' mode.
92              
93             =item C
94              
95             Errors related to GNITS Standards (silent by default).
96              
97             =item C
98              
99             Internal errors. Use C<&prog_error> to send messages over this channel.
100              
101             =item C
102              
103             Constructs compromising the cross-compilation of the package.
104              
105             =item C
106              
107             Warnings related to GNU Coding Standards.
108              
109             =item C
110              
111             Warnings about obsolete features.
112              
113             =item C
114              
115             Warnings about user redefinitions of Automake rules or
116             variables (silent by default).
117              
118             =item C
119              
120             Warnings about non-portable constructs.
121              
122             =item C
123              
124             Warnings about recursive variable expansions (C<$(foo$(x))>).
125             These are not universally supported, but are more portable than
126             the other non-portable constructs diagnosed by C<-Wportability>.
127             These warnings are turned on by C<-Wportability> but can then be
128             turned off separately by C<-Wno-portability-recursive>.
129              
130             =item C
131              
132             Extra warnings about non-portable constructs covering obscure tools.
133              
134             =item C
135              
136             Warnings about weird syntax, unused variables, typos...
137              
138             =item C
139              
140             Warnings about unsupported (or mis-supported) features.
141              
142             =item C
143              
144             Messages output in C<--verbose> mode. Use C<&verb> to send such messages.
145              
146             =item C
147              
148             Informative messages.
149              
150             =back
151              
152             =cut
153              
154             # Initialize our list of error/warning channels.
155             # Do not forget to update &usage and the manual
156             # if you add or change a warning channel.
157              
158             register_channel 'fatal', type => 'fatal', uniq_part => UP_NONE, ordered => 0;
159             register_channel 'error', type => 'error';
160             register_channel 'error-gnu', type => 'error';
161             register_channel 'error-gnu/warn', type => 'error';
162             register_channel 'error-gnits', type => 'error', silent => 1;
163             register_channel 'automake', type => 'fatal', backtrace => 1,
164             header => ("####################\n" .
165             "## Internal Error ##\n" .
166             "####################\n"),
167             footer => "\nPlease contact <$PACKAGE_BUGREPORT>.",
168             uniq_part => UP_NONE, ordered => 0;
169              
170             register_channel 'cross', type => 'warning', silent => 1;
171             register_channel 'gnu', type => 'warning';
172             register_channel 'obsolete', type => 'warning';
173             register_channel 'override', type => 'warning', silent => 1;
174             register_channel 'portability', type => 'warning', silent => 1;
175             register_channel 'extra-portability', type => 'warning', silent => 1;
176             register_channel 'portability-recursive', type => 'warning', silent => 1;
177             register_channel 'syntax', type => 'warning';
178             register_channel 'unsupported', type => 'warning';
179              
180             register_channel 'verb', type => 'debug', silent => 1, uniq_part => UP_NONE,
181             ordered => 0;
182             register_channel 'note', type => 'debug', silent => 0;
183              
184             setup_channel_type 'warning', header => 'warning: ';
185             setup_channel_type 'error', header => 'error: ';
186             setup_channel_type 'fatal', header => 'error: ';
187              
188             =head2 FUNCTIONS
189              
190             =over 4
191              
192             =item C
193              
194             Return the warning category descriptions.
195              
196             =cut
197              
198             sub usage ()
199             {
200 4     4 1 139 return "Warning categories are:
201             cross cross compilation issues
202             gnu GNU coding standards (default in gnu and gnits modes)
203             obsolete obsolete features or constructions (default)
204             override user redefinitions of Automake rules or variables
205             portability portability issues (default in gnu and gnits modes)
206             portability-recursive nested Make variables (default with -Wportability)
207             extra-portability extra portability issues related to obscure tools
208             syntax dubious syntactic constructs (default)
209             unsupported unsupported or incomplete features (default)
210              
211             -W also understands:
212             all turn on all the warnings
213             none turn off all the warnings
214             no-CATEGORY turn off warnings in CATEGORY
215             error treat all enabled warnings as errors";
216             }
217              
218             =item C
219              
220             Signal a programming error (on channel C),
221             display C<$MESSAGE>, and exit 1.
222              
223             =cut
224              
225             sub prog_error ($;%)
226             {
227 0     0 1   my ($msg, %opts) = @_;
228 0           msg 'automake', '', $msg, %opts;
229             }
230              
231             =item C
232              
233             =item C
234              
235             Uncategorized errors.
236              
237             =cut
238              
239             sub error ($;$%)
240             {
241 0     0 1   my ($where, $msg, %opts) = @_;
242 0           msg ('error', $where, $msg, %opts);
243             }
244              
245             =item C
246              
247             =item C
248              
249             Fatal errors.
250              
251             =cut
252              
253             sub fatal ($;$%)
254             {
255 0     0 1   my ($where, $msg, %opts) = @_;
256 0           msg ('fatal', $where, $msg, %opts);
257             }
258              
259             =item C
260              
261             C<--verbose> messages.
262              
263             =cut
264              
265             sub verb ($;%)
266             {
267 0     0 1   my ($msg, %opts) = @_;
268 0 0         $msg = "thread " . threads->tid . ": " . $msg
269             if $perl_threads;
270 0           msg 'verb', '', $msg, %opts;
271             }
272              
273             =item C
274              
275             If C<$CATEGORY> is C, turn on channel C.
276             If it is C, turn C off.
277             Else handle C and C for completeness.
278              
279             =cut
280              
281             sub switch_warning ($)
282             {
283 0     0 1   my ($cat) = @_;
284 0           my $has_no = 0;
285              
286 0 0         if ($cat =~ /^no-(.*)$/)
287             {
288 0           $cat = $1;
289 0           $has_no = 1;
290             }
291              
292 0 0         if ($cat eq 'all')
    0          
    0          
    0          
293             {
294 0           setup_channel_type 'warning', silent => $has_no;
295             }
296             elsif ($cat eq 'none')
297             {
298 0           setup_channel_type 'warning', silent => ! $has_no;
299             }
300             elsif ($cat eq 'error')
301             {
302 0           $warnings_are_errors = ! $has_no;
303             # Set exit code if Perl warns about something
304             # (like uninitialized variables).
305             $SIG{"__WARN__"} =
306 0 0   0     $has_no ? 'DEFAULT' : sub { print STDERR @_; $exit_code = 1; };
  0            
  0            
307             }
308             elsif (channel_type ($cat) eq 'warning')
309             {
310 0           setup_channel $cat, silent => $has_no;
311             #
312             # Handling of portability warnings is trickier. For relevant tests,
313             # see 'dollarvar2', 'extra-portability' and 'extra-portability3'.
314             #
315             # -Wportability-recursive and -Wno-portability-recursive should not
316             # have any effect on other 'portability' or 'extra-portability'
317             # warnings, so there's no need to handle them separately or ad-hoc.
318             #
319 0 0 0       if ($cat eq 'extra-portability' && ! $has_no) # -Wextra-portability
320             {
321             # -Wextra-portability must enable 'portability' and
322             # 'portability-recursive' warnings.
323 0           setup_channel 'portability', silent => 0;
324 0           setup_channel 'portability-recursive', silent => 0;
325             }
326 0 0         if ($cat eq 'portability') # -Wportability or -Wno-portability
327             {
328 0 0         if ($has_no) # -Wno-portability
329             {
330             # -Wno-portability must disable 'extra-portability' and
331             # 'portability-recursive' warnings.
332 0           setup_channel 'portability-recursive', silent => 1;
333 0           setup_channel 'extra-portability', silent => 1;
334             }
335             else # -Wportability
336             {
337             # -Wportability must enable 'portability-recursive'
338             # warnings. But it should have no influence over the
339             # 'extra-portability' warnings.
340 0           setup_channel 'portability-recursive', silent => 0;
341             }
342             }
343             }
344             else
345             {
346 0           return 1;
347             }
348 0           return 0;
349             }
350              
351             =item C
352              
353             Parse the WARNINGS environment variable.
354              
355             =cut
356              
357             # Used to communicate from parse_WARNINGS to parse_warnings.
358             our $_werror = 0;
359              
360             sub parse_WARNINGS ()
361             {
362 0 0   0 1   if (exists $ENV{'WARNINGS'})
363             {
364             # Ignore unknown categories. This is required because WARNINGS
365             # should be honored by many tools.
366             # For the same reason, do not turn on -Werror at this point, just
367             # record that we saw it; parse_warnings will turn on -Werror after
368             # the command line has been processed.
369 0           foreach (split (',', $ENV{'WARNINGS'}))
370             {
371 0 0         if (/^(no-)?error$/)
372             {
373 0           $_werror = !defined $1;
374             }
375             else
376             {
377 0           switch_warning $_;
378             }
379             }
380             }
381             }
382              
383             =item C
384              
385             Parse the argument of C<--warning=CATEGORY> or C<-WCATEGORY>.
386             C<@CATEGORIES> is the accumulated set of warnings categories.
387             Use like this:
388              
389             Autom4te::GetOpt::parse_options (
390             # ...
391             'W|warnings=s' => \@warnings,
392             )
393             # possibly call set_strictness here
394             parse_warnings @warnings;
395              
396             =cut
397              
398             sub parse_warnings (@)
399             {
400 0     0 1   foreach my $cat (map { split ',' } @_)
  0            
401             {
402 0 0         if ($cat =~ /^(no-)?error$/)
    0          
403             {
404 0           $_werror = !defined $1;
405             }
406             elsif (switch_warning $cat)
407             {
408 0           msg 'unsupported', "unknown warning category '$cat'";
409             }
410             }
411              
412 0 0         switch_warning ($_werror ? 'error' : 'no-error');
413             }
414              
415             =item C
416              
417             Merge the warnings categories in the environment variable C
418             with the warnings categories in C<@CATEGORIES>, and return a new
419             value for C. Values in C<@CATEGORIES> take precedence.
420             Use like this:
421              
422             local $ENV{WARNINGS} = merge_WARNINGS @additional_warnings;
423              
424             =cut
425              
426             sub merge_WARNINGS (@)
427             {
428 0     0 1   my $werror = '';
429 0           my $all_or_none = '';
430 0           my %warnings;
431              
432 0   0       my @categories = split /,/, $ENV{WARNINGS} || '';
433 0           push @categories, @_;
434              
435 0           foreach (@categories)
436             {
437 0 0         if (/^(?:no-)?error$/)
    0          
438             {
439 0           $werror = $_;
440             }
441             elsif (/^(?:all|none)$/)
442             {
443 0           $all_or_none = $_;
444             }
445             else
446             {
447             # The character class in the second match group is ASCII \S minus
448             # comma. We are generous with this because category values may come
449             # from WARNINGS and we don't want to assume what other programs'
450             # syntaxes for warnings categories are.
451 0 0         /^(no-|)([\w\[\]\/\\!"#$%&'()*+-.:;<=>?@^`{|}~]+)$/
452             or die "Invalid warnings category: $_";
453 0           $warnings{$2} = $1;
454             }
455             }
456              
457 0           my @final_warnings;
458 0 0         if ($all_or_none)
459             {
460 0           push @final_warnings, $all_or_none;
461             }
462             else
463             {
464 0           foreach (sort keys %warnings)
465             {
466 0           push @final_warnings, $warnings{$_} . $_;
467             }
468             }
469 0 0         if ($werror)
470             {
471 0           push @final_warnings, $werror;
472             }
473              
474 0           return join (',', @final_warnings);
475             }
476              
477             =item C
478              
479             Configure channels for strictness C<$STRICTNESS_NAME>.
480              
481             =cut
482              
483             sub set_strictness ($)
484             {
485 0     0 1   my ($name) = @_;
486              
487 0 0         if ($name eq 'gnu')
    0          
    0          
488             {
489 0           setup_channel 'error-gnu', silent => 0;
490 0           setup_channel 'error-gnu/warn', silent => 0, type => 'error';
491 0           setup_channel 'error-gnits', silent => 1;
492 0           setup_channel 'portability', silent => 0;
493 0           setup_channel 'extra-portability', silent => 1;
494 0           setup_channel 'gnu', silent => 0;
495             }
496             elsif ($name eq 'gnits')
497             {
498 0           setup_channel 'error-gnu', silent => 0;
499 0           setup_channel 'error-gnu/warn', silent => 0, type => 'error';
500 0           setup_channel 'error-gnits', silent => 0;
501 0           setup_channel 'portability', silent => 0;
502 0           setup_channel 'extra-portability', silent => 1;
503 0           setup_channel 'gnu', silent => 0;
504             }
505             elsif ($name eq 'foreign')
506             {
507 0           setup_channel 'error-gnu', silent => 1;
508 0           setup_channel 'error-gnu/warn', silent => 0, type => 'warning';
509 0           setup_channel 'error-gnits', silent => 1;
510 0           setup_channel 'portability', silent => 1;
511 0           setup_channel 'extra-portability', silent => 1;
512 0           setup_channel 'gnu', silent => 1;
513             }
514             else
515             {
516 0           prog_error "level '$name' not recognized";
517             }
518             }
519              
520             =back
521              
522             =head1 SEE ALSO
523              
524             L
525              
526             =head1 HISTORY
527              
528             Written by Alexandre Duret-Lutz EFE.
529              
530             =cut
531              
532             1;
533              
534             ### Setup "GNU" style for perl-mode and cperl-mode.
535             ## Local Variables:
536             ## perl-indent-level: 2
537             ## perl-continued-statement-offset: 2
538             ## perl-continued-brace-offset: 0
539             ## perl-brace-offset: 0
540             ## perl-brace-imaginary-offset: 0
541             ## perl-label-offset: -2
542             ## cperl-indent-level: 2
543             ## cperl-brace-offset: 0
544             ## cperl-continued-brace-offset: 0
545             ## cperl-label-offset: -2
546             ## cperl-extra-newline-before-brace: t
547             ## cperl-merge-trailing-else: nil
548             ## cperl-continued-statement-offset: 2
549             ## End: