our $err_file;
+our @warn_ena_dfl = map { $_ => 1 } qw(
+ local+global
+ single-char-var
+ unknown-warning
+ broken-var-ref
+);
+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) = @_;
+ our %warn_dedupe;
+ return 0 if $warn_dedupe{$err_file,$.,$wk,$m}++;
+ wrncore($wk, "${err_file}:$.: $m");
}
sub ddbl_only ($) {
$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\:local\+global\s+(\S.*)$##) {
+ foreach my $vn (split /\s+/, $1) {
+ $vn =~ s{^$esc}{};
+ $varref{$vn}{NoWarn} = 1;
+ }
+ next;
} elsif (s#^\s*$esc\:(?=(-?)include|macro)##) {
$buffering_output='';
- } elsif (m#^\s*$esc\:([a-z][-0-9a-z_]*)#) {
+ } elsif (m#^\s*$esc\:([a-z][-+0-9a-z_]*)#) {
err "unknown directive &:$1 or bad argumnt syntax";
} elsif (s{^\s*${esc}TARGETS(?:_([0-9a-zA-Z_]+))?(?=\W)}{}) {
my $t = $1 // 'all';
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}) {
+ wrn 'broken-var-ref',
+ 'broken $&... expansion; you probably meant &$';
+ }
elsif (m{^\(($esc)?([^()\$]+)\)} ||
m{^\{($esc)?([^{}\$]+)\}}) {
$note_varref->($2,!!$1);
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);
}
oraw "include \$(SUBDIRMK_MAKEFILES)\n";
}
+sub flmap ($) { local ($_) = @_; s{:(\d+)$}{ sprintf ":%10d", $1 }e; $_; }
+
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";
+ next if $vv->{NoWarn};
+ wrncore 'local+global', "saw both $vn and &$vn" or return;
foreach my $amp ('', 1) {
printf STDERR " saw %s%s at %s\n",
($amp ? '&' : ''), $vn, $_
- foreach sort keys %{ $vv->{$amp} };
+ foreach
+ sort { flmap($a) cmp flmap($b) }
+ keys %{ $vv->{$amp} };
}
}
}
+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();