chiark / gitweb /
Macro assistance part 1 - macro directive
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 28 Dec 2019 00:36:50 +0000 (00:36 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 30 Dec 2019 11:35:15 +0000 (11:35 +0000)
Define the &:macro directive, which is a dollar-doubled version of
make's own `define'.

We must introuce a new concept of `nesting', for when "the content of
the construct is $-doubled" in the words of the README.  The
implementation is in the main process_input_mk function: it is a
multi-line scope of some kind with an ad-hoc ending condition, and its
own dollar-doubling setting.

We will also want a convenient syntax for $(eval $(call...)), which
we're going to introduce in a moment.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
README
generate
tests/filter/extract-doctest

diff --git a/README b/README
index d750cb8..130a1c7 100644 (file)
--- a/README
+++ b/README
@@ -331,6 +331,15 @@ Dollar doubling and macro assistance
 &$-            Stops dollar-doubling
        Both are idempotent and local to the file or context.
 
+Sometimes we will show $'s being doubled inside another construct.
+This means the content of the construct is $-doubled: $-doubling is
+locally enabled, and restored afterwards.
+
+&:macro NAME   =>      define NAME
+STUFF $ THINGS ..      STUFF $$ THINGS
+&:endm         ..      endef
+       NAME is processed for &
+
 While dollar-doubling:
 - - - - - - - - - - -
 
index ec47866..3ccfa0d 100755 (executable)
--- 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";
@@ -238,6 +254,9 @@ 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 $_ ";
            }
index 35870ce..57f5313 100755 (executable)
@@ -138,6 +138,8 @@ sub writeout ($) {
                  'dollar doubling',
                  sub {
                      my ($e) = @_;
+                     # adhoc: skip &:macro in already-doubling part
+                     return 0 if $e->{In} =~ m{^\&\:macro};
                      return 0 if $e->{CQ};
                      return $e->{DD} || !grep {
                          # If there are two entries with the same In,