From 62ddb6b1bd58afe028dfe8799aa86bc9bd4b1a48 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 28 Dec 2019 13:55:12 +0000 Subject: [PATCH] Warning reporting: Warning suppression system Signed-off-by: Ian Jackson --- README | 33 +++++++++++++++++++++++ generate | 52 ++++++++++++++++++++++++++++++++---- tests/filter/stderr.expected | 4 +-- 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/README b/README index e5e937f..98fe313 100644 --- a/README +++ b/README @@ -269,6 +269,14 @@ So pathname syntax is a subset of: `all' is extra special: every directory has an `all' target, which corresponds to &TARGETS. +&:warn [!]WARNTAG ... + Suppress (with !) or re-enable (without !) warnings tagged + WARNTAG (see section `Warnings', below). The suppression list + is reset at the start of processing in each subdirectory. + Warnings that appear at the end of processing are controlled + by the final warning state after processing all the toplevel + input files (including Final.sd.mk). + &:changequote NEWQUOTE changes the escape sequence from & to literally NEWQUOTE NEWQUOTE may be any series of of non-whitespace characters, @@ -373,6 +381,31 @@ In more detail, with all the various options laid out: (This assumes you have appropriate make variables src, PWD and abs_src.) +Warnings +-------- + +subdirmk's `generate' program, which does the acual &-substitution, +can produce some warnings about your .sd.mk files. These can be +suppressed with the &:warn directive. The warning tags are: + + local+global + The same VARNAME was used both with and without an & prefix. + This can be confusing. Also, if you avoid this then you will + get a warning iff you accidentally leave off a needed &. + + single-char-var + A variable expansion like $FBAR. make's expansion rules + interpret this as $(F)BAR. It's normally better to write + it this way, at least if the variable expansion is followed + by more letters. Note that &$FOO works differently to + raw make: it expands to $(sub_dir_FOO). + + unknown-warning + &:warn was used to try to enable a warning that this version + of subdirmk does not understand. (Note that an attempt to + *dis*able an unknown warning is only reported if some other + warning was issued which might have been disabled.) + Subdirectory and variable naming -------------------------------- diff --git a/generate b/generate index 1380918..3caf4e6 100755 --- a/generate +++ b/generate @@ -173,14 +173,32 @@ sub set_dir_vars ($) { our $err_file; +our @warn_ena_dfl = map { $_ => 1 } qw( + local+global + single-char-var + unknown-warning +); +our %warn_ena = @warn_ena_dfl; + +our $warned; +our %warn_unk; + sub err ($) { my ($m) = @_; die "subdirmk: ${err_file}:$.: $m\n"; } -sub wrn ($) { - my ($m) = @_; - print STDERR "subdirmk: warning: ${err_file}:$.: $m\n"; +sub wrncore ($$) { + my ($wk,$m) = @_; + return 0 unless $warn_ena{$wk} // warn "internal error $wk ?"; + $warned++; + print STDERR "subdirmk: warning ($wk): $m\n"; + return 1; +} + +sub wrn ($$) { + my ($wk,$m) = @_; + wrncore($wk, "${err_file}:$.: $m"); } sub ddbl_only ($) { @@ -257,6 +275,20 @@ sub process_input_mk ($$$$) { $pop_nest->('macro'); od "endef\n"; next; + } elsif (s#^\s*$esc\:warn\s+(\S.*)$##) { + foreach my $wk (split /\s+/, $1) { + my $yes = $wk !~ s{^!}{}; + if (defined $warn_ena{$wk}) { + $warn_ena{$wk} = $yes; + next; + } elsif ($yes) { + wrn 'unknown-warning', + "unknown warning $wk requested"; + } else { + $warn_unk{$wk} //= "$f:$."; + } + } + next; } elsif (s#^\s*$esc\:(?=(-?)include|macro)##) { $buffering_output=''; } elsif (m#^\s*$esc\:([a-z][-0-9a-z_]*)#) { @@ -289,7 +321,7 @@ sub process_input_mk ($$$$) { od $2; if (s{^\$}{}) { od $&; } elsif (m{^[a-zA-Z]\w}) { - wrn + wrn 'single-char-var', 'possibly confusing unbracketed single-char $-expansion'; } elsif (m{^\(($esc)?([^()\$]+)\)} || @@ -402,6 +434,7 @@ sub process_subtree ($$) { my @childpath = (@$path, $child->[0]); my $child_subdir = join '/', @childpath; mkdir $child_subdir or $!==EEXIST or die "mkdir $child_subdir: $!\n"; + local %warn_ena = @warn_ena_dfl; push @{ $targets{$_} }, $child_subdir foreach process_subtree($child, \@childpath); } @@ -480,7 +513,7 @@ sub print_varref_warnings () { foreach my $vn (sort keys %varref) { my $vv = $varref{$vn}; next unless $vv->{''} && $vv->{1}; - print STDERR "subdirmk: warning: saw both $vn and &$vn\n"; + wrncore 'local+global', "saw both $vn and &$vn" or return; foreach my $amp ('', 1) { printf STDERR " saw %s%s at %s\n", ($amp ? '&' : ''), $vn, $_ @@ -491,7 +524,16 @@ sub print_varref_warnings () { } } +sub print_warning_warnings () { + return unless $warned; + foreach my $wk (sort keys %warn_unk) { + wrncore 'unknown-warning', + "$warn_unk{$wk}: attempt to suppress unknown warning(s) \`$wk'"; + } +} + build_tree(); process_tree(); print_varref_warnings(); +print_warning_warnings(); install_output_files(); diff --git a/tests/filter/stderr.expected b/tests/filter/stderr.expected index 0700625..5568e62 100644 --- a/tests/filter/stderr.expected +++ b/tests/filter/stderr.expected @@ -1,5 +1,5 @@ -subdirmk: warning: ./Dir.sd.mk:8: possibly confusing unbracketed single-char $-expansion -subdirmk: warning: saw both WARN and &WARN +subdirmk: warning (single-char-var): ./Dir.sd.mk:8: possibly confusing unbracketed single-char $-expansion +subdirmk: warning (local+global): saw both WARN and &WARN saw WARN at ./Dir.sd.mk:6 saw WARN at ./Dir.sd.mk:9 saw &WARN at ./Dir.sd.mk:7 -- 2.30.2