X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=generate;h=bcbbf79dde7d86b5ad1b3ff5ba3b30b1ca2359d8;hb=d145782ea0dc424dae204d1be1d07eac51c87ccf;hp=61bbd507c683adc89d5fe648260737a7c0492e73;hpb=08e825fede28f22ce3fbaf494c3e06360ed74d7a;p=subdirmk.git diff --git a/generate b/generate index 61bbd50..bcbbf79 100755 --- a/generate +++ b/generate @@ -3,6 +3,7 @@ # subdirmk - &-filter (makefile generation program) # Copyright 2019 Ian Jackson # SPDX-License-Identifier: LGPL-2.0-or-later +# There is NO WARRANTY. # # $(srcdir)/subdirmk/generate [--srcdir=SRCDIR] [--] SUBDIR... # @@ -153,6 +154,7 @@ END } our %varref; +our %varref_exp; our ($dir_prefix, $dir_suffix, $dir_name, $var_prefix, $var_prefix_name); @@ -177,6 +179,7 @@ our @warn_ena_dfl = map { $_ => 1 } qw( local+global single-char-var unknown-warning + broken-var-ref ); our %warn_ena = @warn_ena_dfl; @@ -185,7 +188,9 @@ our %warn_unk; sub err ($) { my ($m) = @_; - die "subdirmk: ${err_file}:$.: $m\n"; + die defined $err_file + ? "subdirmk: ${err_file}:$.: $m\n" + : "subdirmk: $m\n"; } sub wrncore ($$) { @@ -198,6 +203,8 @@ sub wrncore ($$) { sub wrn ($$) { my ($wk,$m) = @_; + our %warn_dedupe; + return 0 if $warn_dedupe{$err_file,$.,$wk,$m}++; wrncore($wk, "${err_file}:$.: $m"); } @@ -231,8 +238,8 @@ sub process_input_mk ($$$$) { local $err_file=$f; my %srcdirmap = ( - '^' => "\$(top_srcdir)${dir_suffix}", - '~' => "\$(top_srcdir)", + '^' => "\${top_srcdir}${dir_suffix}", + '~' => "\${top_srcdir}", ); my %pfxmap = ( '' => $dir_prefix, @@ -259,7 +266,8 @@ sub process_input_mk ($$$$) { # accurate, since it is only going to be used for advice to the user. my $note_varref = sub { my ($vn,$amp) = @_; - $varref{$vn}{$amp}{"$f:$."} = 1; + my $exp = !!$varref_exp{$vn}{$amp}; + $varref{$vn}{$exp}{$amp}{"$f:$."} = 1; }; while (<$input>) { @@ -291,8 +299,9 @@ sub process_input_mk ($$$$) { next; } elsif (s#^\s*$esc\:local\+global\s+(\S.*)$##) { foreach my $vn (split /\s+/, $1) { - $vn =~ s{^$esc}{}; - $varref{$vn}{NoWarn} = 1; + my $pos = !($vn =~ s{^!}{}); + my $amp = $vn =~ s{^$esc}{}; + $varref_exp{$vn}{!!$amp} = $pos; } next; } elsif (s#^\s*$esc\:(?=(-?)include|macro)##) { @@ -330,6 +339,10 @@ sub process_input_mk ($$$$) { 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); @@ -343,7 +356,7 @@ sub process_input_mk ($$$$) { elsif (m{^(?=$caps_re)}) { od $var_prefix } elsif (s{^\$([A-Za-z]\w+)}{}) { $note_varref->($1,1); - od "\$(${var_prefix}$1)"; + od "\${${var_prefix}$1}"; } elsif (s{^([~^]?)(?=$lc_re)}{}) { od $pfxmap{$1} } elsif (s{^_}{}) { od $var_prefix } @@ -354,10 +367,10 @@ sub process_input_mk ($$$$) { elsif (s{^\$\-}{}) { $ddbl=undef; } elsif (s{^\$\+}{}) { $ddbl=1; } elsif (s{^\$\(}{}) { - ddbl_only($&); oud "\$("; + ddbl_only($&); oud "\${"; $note_varref->($2,!!$1) if m{^($esc)?([^()\$]+\))}; } - elsif (s{^\$(\d+)}{}) { ddbl_only($&); oud "\$($1)"; } + elsif (s{^\$(\d+)}{}) { ddbl_only($&); oud "\${$1}"; } elsif (s{^\$\{}{}) { err 'macro invocation cannot be re-$-doubled' if $ddbl; od '${eval ${call '; @@ -428,6 +441,8 @@ sub process_subtree ($$) { #use Data::Dumper; #print STDERR Dumper(\@_); + local %varref_exp; + my $dir_prefix = dir_prefix($path); # ^ this is the only var which we need before we come back from # the recursion. @@ -518,16 +533,20 @@ 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}; - next if $vv->{NoWarn}; + next unless $vv->{''}{''} && $vv->{''}{1}; wrncore 'local+global', "saw both $vn and &$vn" or return; + foreach my $exp ('', 1) { foreach my $amp ('', 1) { - printf STDERR " saw %s%s at %s\n", + printf STDERR + ($exp + ? " expectedly saw %s%s at %s\n" + : " saw %s%s at %s\n"), ($amp ? '&' : ''), $vn, $_ foreach sort { flmap($a) cmp flmap($b) } - keys %{ $vv->{$amp} }; + keys %{ $vv->{$exp}{$amp} }; } + } } }