chiark / gitweb /
Syntax: Incompatible change: Use &{ not &${ for macros
[subdirmk.git] / generate
index f571fa19d196efc9aa62299a487a095f0dba2724..c2dc42da1ae75eb7ca8f17c1c0e0c635de22541c 100755 (executable)
--- 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);
@@ -186,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 ($$) {
@@ -262,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>) {
@@ -294,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)##) {
@@ -361,15 +367,15 @@ 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{^\$\{}{}) {
+           elsif (s{^\$(\d+)}{}) { ddbl_only($&); oud "\${$1}"; }
+           elsif (s{^\{}{}) {
                err 'macro invocation cannot be re-$-doubled' if $ddbl;
                od '${eval ${call ';
                $evalcall_brackets = 1;
-               $push_nest->('eval',1, '&${...}');
+               $push_nest->('eval',1, '&{...}');
                $note_varref->($2,!!$1) if m{^\s*($esc)?([^,{}\$]+)};
            } elsif (s{^([~^]?)(?=[ \t])}{}) {
                my $prefix = $pfxmap{$1} // die "internal error ($1?)";
@@ -435,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.
@@ -525,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} };
        }
+        }
     }
 }