cons-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Perl function in a Command method


From: Gary Oberbrunner
Subject: Re: Perl function in a Command method
Date: Wed, 22 Nov 2000 14:11:47 -0500 (EST)

>>>>> "ZD" == Zachary Deretsky <address@hidden> writes:

  ZD> Is there a way to call a perl subroutine defined in the same
  ZD> Conscript file from a command method?

Funny you should ask; I have a patch for this also.  You just put
[perl] in the front of your command, then it's executed directly in
your perl.  Hope it's not too obnoxious to send it to the whole list.

*HOWEVER*, there are some issues regarding name spaces with this kind
of thing (same kind of thing happens with perl code in QuickScans).
Cons reads each Conscript into the "script" package, after deleting
all vars from that package (to clear cruft left around in other
Conscripts).  This makes it more difficult to refer to variables in
the Conscript.  Specifically, you can't refer to the cons
environments: they're gone by the time commands are run.  I've been
kicking around some ideas about putting each Conscript into its *own*
package rather than reusing "script" each time, but I don't really
know what kinds of issues this would create.  (Anyone else but me care
about this?)

What I usually do is put anything I'll need in the [perl] commands
into the 'main' package, but you can do it however you like.

Here's my patch.  This is against a fairly old cons version, but it
shouldn't be too hard to shoehorn into recent builds, I hope.  Let me
know how you like it!

--- cons-18dev  Wed Feb 16 13:32:41 2000
+++ cons        Thu May 11 10:29:04 2000
@@ -1183,6 +1183,23 @@
        }
        if ($param::build) {
 
+         if ($com =~ /^\[perl\]\s*/) {
+           my $perlcmd = $';
+           my $status;
+           {
+             package script;
+             $status = eval $perlcmd;
+           }
+           if (!defined($status)) {
+               warn "$0: *** Error during perl command eval: address@hidden";
+               return undef;
+           }
+           elsif ($status == 0) {
+               warn "$0: *** Perl command returned $status (this indicates an 
error).\n";
+               return undef;
+           }
+           next;
+         }
          #---------------------
          # Can't fork on Win32
          #---------------------
@@ -4425,6 +4442,47 @@
 command which is expected to be available. If it isn't available, you will,
 of course, get an error.
 
+If any command (even one within a multi-line command) begins with
+C<[perl]>, the remainder of that command line will be evaluated by
+the running perl instead of being forked by the shell.  If an error
+occurs in parsing the perl or if the perl expression returns 0, the
+command will be considered to have failed.  For instance, here is a
+simple command which creates a file C<foo> directly from perl:
+
+  $env = new cons();
+  Command $env 'foo',
+    qq([perl] open(FOO,'>foo');print FOO "hi\\n"; close(FOO); 1);
+
+Note that when the command is executed, you are in the C<script>
+package so you can call perl functions you've defined in your
+Construct or Conscript.  However variables you create in the C<script>
+package (including your cons environments) will not be visible.  In
+order to use variables from your script you will have to copy them
+into another package, e.g. C<main>, as in the following example, which
+calls C<create_file> to create C<foo>, and as well dynamically
+creates a new target C<bar> (using C<$env>) and adds a command to
+build it.
+
+  sub create_file {
+    open(FOO, ">$_[0]") || return 0;
+    print FOO "hi\n";
+    close(FOO);
+    AddTarget $main::env 'bar';
+    Command $main::env 'bar', 'echo BAR > %>';
+    1;
+  }
+
+  $env = new cons();
+  $main::env = $env;
+  Command $env 'foo', qq([perl] create_file('foo'););
+
+The perl command (including the [perl] part) will be used to generate
+the signature for the derived file, but if you modify any methods,
+such as C<create_file> above, that won't cause the target to be
+rebuilt.  Caveat user.
+
+
+    
 Cons normally prints a command before executing it.  This behavior is
 suppressed if the first character of the command is C<@>.  Note that
 you may need to separate the C<@> from the command name or escape it to
-- 
. . . . . . . . . . . . . . . . . . . . . . . . .
Gary Oberbrunner                address@hidden
GenArts, Inc.                   Tel: 617-492-2888
8 Clinton Street                Fax: 617-492-2852
Cambridge, MA 02139 USA         http://web.genarts.com

reply via email to

[Prev in Thread] Current Thread [Next in Thread]