X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?p=subdirmk.git;a=blobdiff_plain;f=generate;h=4bc1e74eb712a3a799bb9ee19912189d58b91e08;hp=ec478665e89f954385f3ea5df1d2f8e3fcc49e7a;hb=57a9bee6bf459a1499729159007bfd95110b94e2;hpb=f68bcc4648c8cbe549e37159df8bb488178c510c diff --git a/generate b/generate index ec47866..4bc1e74 100755 --- a/generate +++ b/generate @@ -180,13 +180,29 @@ sub process_input_mk ($$$$) { $pfxmap{$_} = $srcdirmap{$_}.'/' foreach keys %srcdirmap; local $ddbl; + my @nest = (['']); + + my $push_nest = sub { + my ($nk, $nndbl) = @_; + unshift @nest, [ $nk, $ddbl ]; + $ddbl = $nndbl; + }; + my $pop_nest = sub { + my ($nk) = @_; + die unless $nest[0][0] eq $nk; + $ddbl = (shift @nest)[1]; + }; while (<$input>) { if (s#^\s*$esc\:changequote\s+(\S+)\s+$##) { $$esclitr = $1; $set_esc->(); next; - } elsif (s#^\s*$esc\:(?=(-?)include)##) { + } elsif (s#^\s*$esc\:endm\s+$##) { + $pop_nest->('Macro'); + od "endef\n"; + next; + } elsif (s#^\s*$esc\:(?=(-?)include|macro)##) { $buffering_output=''; } elsif (m#^\s*$esc\:([a-z][-0-9a-z_]*)#) { die "unknown directive $1"; @@ -197,8 +213,19 @@ sub process_input_mk ($$$$) { } for (;;) { die if $ddbl && defined $buffering_output; - unless (s{^(.*?)$esc}{}) { od $_; last; } + unless ($nest[0][0] eq 'Eval' + ? s{^(.*?)($esc|[{}])}{} + : s{^(.*?)($esc)}{}) { od $_; last; } od $1; + if ($2 eq '{') { + $ddbl++; + next; + } elsif ($2 eq '}') { + next if --$ddbl; + $pop_nest->('Eval'); + od '}}'; + next; + } if (s{^\\$esc}{}) { od "$$esclitr" } elsif (s{^\\\$}{}) { oud '$' } elsif (s{^\\\s+$}{}) { } @@ -215,7 +242,11 @@ sub process_input_mk ($$$$) { elsif (s{^\$\+}{}) { $ddbl=1; } elsif (s{^\$\(}{}) { die unless $ddbl; oud "\$("; } elsif (s{^\$(\d+)}{}) { die unless $ddbl; oud "\$($1)"; } - elsif (s{^([~^]?)(?=[ \t])}{}) { + elsif (s{^\$\{}{}) { + die if $ddbl; + od '${eval ${call '; + $push_nest->('Eval',1); + } elsif (s{^([~^]?)(?=[ \t])}{}) { my $prefix = $pfxmap{$1} // die; my $after=''; if (m{([ \t])$esc}) { ($_,$after) = ($`, $1.$'); } @@ -238,11 +269,15 @@ sub process_input_mk ($$$$) { my $subf = "$srcdir/$2"; process_input_mk($targets, $subf, $esclitr, $1); od "\n"; + } elsif (m#^macro\s+(\S+)\s+$#) { + od "define $1\n"; + $push_nest->('Macro', 1); } else { die "internal error buffering directive $_ "; } } } + die "unclosed $nest[0][0]" if $nest[0][0]; $input->error and die "read $f: $!\n"; close $input or die "close $f: $!\n"; }