Hi Alan,

Thanks for the reply.

> >.... I'll apologise up front if this idea has been discussed before.
> 
> This is new :)

That's always nice!

> You may have done this, but how about =item / =back bracketing for other 
> options like
> "-l" that can occur multiple times? One =item bracket could generate multiple 
> "-l".

It's an idea, certainly.  I don't currently do this, mainly because
it's was easier to code for the --option=value or -O value general
cases.  The whole thing only took an evenings tinkering.

> On the other hand, why not process the "=item PAR --addlist" into multiple 
> "--addfile"
> options and avoid the extra file? It's equivalent.

This is a nice idea.  I'll look at doing just that.  The --addlist
option is the only argument specialisation at the moment anyway.

> At the very least, show it to us, and I'll add it to the contrib/ directory !

The code is below.  There are naturally lots of places it could be
improved, and it's currently hardwired to use a windows directory
separator when locating pp.  Watch this space, I guess, for v0.2 ;-)

Cheers,
Robin

#!/usr/bin/perl -w

####################################################################
#        File: pppp.pl
# Description: Preprocess a Perl file for packaging by the PAR pp
#              tool.
#
# (c) Robin Macharg, 2005
#
# You are free to distribute this code under the same terms as Perl.
#
# Discussion
#
#   The Perl ARchiver (PAR) provides a mechanism by which Perl files
#   can be packaged as self-contained executables, using a utility
#   called 'pp'.  This script allows a user to encode configuration
#   information for pp/PAR within the pod documentation.  This is
#   done with a series of "=head2 PAR ..." pod clauses.  Additional
#   information is contained within the pod section following the
#   "=head2" clause, e.g.
#
#     =head2 PAR -A addfile.txt
#
#      C:\temp\addfile1.txt;/path/to/adfiles/addfile1.txt
#      C:\temp\addfile2.txt;/path/to/adfiles/addfile2.txt
#      C:\temp\addfile3.txt;/path/to/adfiles/addfile3.txt
#
#     =head2 PAR -c
#
#   The name pppp was suggested by Doug Smith.
#
# Revision History
#
# Date         Author Comment
# ------------------------------------------------------------------
# 10/03/2005 - RMM  - RMM = Robin Macharg
#                     Created.
####################################################################

# Pragmata
use strict;
use warnings;
use Config;

# Global variables
my $options = "";
my $pp = $Config{'scriptdir'} . '\pp.bat'; # pp command
my $input_file = $ARGV[0];

####################################################################
##
## Main code
##
####################################################################

# Slurp the file in
undef $/;
my $file = <>;

# iterate over PAR pod clauses
while ($file =~ m/
                    ^
                    =head2    # head2 pod clause
                    \s+
                    PAR       # that is a PAR directive
                    \s+
                    (.*)      # and contains stuff
                /xgm) {
    my @tokens = split / /, $1; # Tokenise the option
    
    # process PAR/pp options
    SWITCH: {
             
        # Add files to our archive.  Files can optionally be given in
        # the POD block
        $tokens[0] =~ /--addlist=(.*)/ && do {
            my $filename = $1;
            ( my $addfiletext, pos $file ) = get_pod_block($file, pos $file);
            write_file($filename, $addfiletext); # write out our addfile
            $options .= " " . join " ", @tokens;
            last SWITCH;
        };
        $tokens[0] =~ /-A/ && do {
            my $filename = $tokens[1];
            ( my $addfiletext, pos $file ) = get_pod_block($file, pos $file);
            write_file($filename, $addfiletext); # write out our addfile
            $options .= " " . join " ", @tokens;
            last SWITCH;
        };
        
        # Process simple options.  Probably overkill since they're processed by
        # the default action, but it does allow us to extend the code easily.
        
        # Catch-all for simple options
        $tokens[0] =~ /-[aBcCdxghmnpPrsSTV]/ && do {
            $options .= " " . $tokens[0];
            last SWITCH;
        };
        
        # verbose simple options
        my $verbosesimpleoptions = "bundle|clean|compile|dependent|" .
                                   "execute|gui|help|multiarch|noscan|" .
                                   "par|perlscript|run|save|sign|" .
                                   "tempcache|version";
        $tokens[0] =~ /--[$verbosesimpleoptions]/ && do {
            $options .= " " . $tokens[0];
            last SWITCH;
        };
        
        # simple options with value
        $tokens[0] =~ /-[eXfiINlLFMovz]/ && do {
            $options .= " " . join " ", @tokens;
            last SWITCH;
        };
        
        # verbose valued options
        my $verbosevaluedoptions = "eval|exclude|filter|icon|info|" .
                                   "lib|link|log|modfilter|module|" .
                                   "output|verbose|compress";
        $tokens[0] =~ /--[$verbosevaluedoptions]=(.*)/ && do {
            $options .= " " . $tokens[0];
            last SWITCH;
        };
        
        # Pass unknown options verbatim - the user's probably right
        $options .= " " . join " ", @tokens;
    }
}

# run 'pp'
system ("$pp $options $input_file") == 0 ||
    die "Unable to run pp: $!";

exit 0;

####################################################################
#    Function: get_pod_block
# Description: extract the body of a pod block
#   Arguments: $file - the text to extract from
#              $pos  - the position to start matching from.
#     Returns: a block of text, stripped of leading and trailing
#              whitespace and the new position to start matching
#              from.
####################################################################
sub get_pod_block {
    my ($file, $pos) = @_;
 
    pos $file = $pos;
    $file =~ m/
                        \s*    # leading whitespace
                        (.*?)  # interesting stuff
                        \s*    # trailing whitespace
                        ^=     # another pod clause
                    /mxgs;
    my $textblock = $1;
    $textblock =~ s/^ //gm; # chop off leading whitespace

    # return our two values, backing up 1 char over the new pod clause
    # start '='
    return ($textblock, ( pos $file ) - 1);
}

####################################################################
#    Function: write_file
# Description: write a file
#   Arguments: $filename
#              $contents
#     Returns:
####################################################################
sub write_file {
    my ($filename, $contents) = @_;
    open FILEOUT, ">$filename" ||
        die "Unable to open file $filename for writing: $!";
    print FILEOUT $contents;
    close FILEOUT;
}

Reply via email to