package Module::Build::Functions::DSL; use strict; use vars qw( $VERSION ); BEGIN { $VERSION = '0.04'; *inc::Module::Build::Functions::DSL::VERSION = *VERSION; @inc::Module::Build::Functions::DSL::ISA = __PACKAGE__; } sub import { my $package = shift; # Read in the rest of the Makefile.PL open 0 or die "Couldn't open $0: $!"; my $dsl; SCOPE: { local $/ = undef; $dsl = join "", <0>; } # Change inc::Module::Build::Functions::DSL to the regular one. # Remove anything before the use inc::... line. $dsl =~ s/.*?^\s*use\s+(?:inc::)?$package(\b[^;]*);\s*\n//sm; # Stripping leading prefix $package =~ s/^\Qinc\E:://; my $code = $package->get_header_code(@_); # Execute the header code if (ref $code eq 'CODE') { eval { &$code() } } else { eval $code } print STDERR "Failed to execute the generated code: $@" if $@; # Add the DSL plugin to the list of packages in /inc Module::Build::Functions::copy_package($package); # Convert the basic syntax to code $code = "package main;\n\n" . dsl2code($dsl) . "\n\nWriteAll();\n"; # Execute the script eval $code; print STDERR "Failed to execute the generated code: $@" if $@; exit(0); } ## end sub import sub get_header_code { my ($self, @import_params) = @_; # Load inc::Module::Build::Functions as we would in a regular Makefile.Pl return sub { package main; require inc::Module::Build::Functions; inc::Module::Build::Functions->import(@import_params); } } sub dsl2code { my $dsl = shift; # Split into lines and strip blanks my @lines = grep {/\S/} split /[\012\015]+/, $dsl; # Each line represents one command my @code = (); foreach my $line (@lines) { # Split the lines into tokens my @tokens = split /\s+/, $line; # The first word is the command my $command = shift @tokens; my @params = (); my @suffix = (); while (@tokens) { my $token = shift @tokens; my $next_token; my $token_quoted; if ( $token =~ /^(\'|\")/ ) { $token_quoted = 1; if ( $token !~ /(\'|\")$/ ) { do { $next_token = shift @tokens; $token .= ' ' . $next_token if $next_token; } while ( $next_token && $next_token !~ /(\'|\")$/ ); } } ## end if ( $token =~ /^(\'|\")/) if ( $token eq 'if' or $token eq 'unless' ) { # This is the beginning of a suffix push @suffix, $token; push @suffix, @tokens; last; } else { # Convert to a string $token =~ s/([\\\'\"])/\\$1/g unless $token_quoted; push @params, $token_quoted ? $token : "'$token'"; } } ## end while (@tokens) # Merge to create the final line of code @tokens = ( $command, @params ? join( ', ', @params ) : (), @suffix ); push @code, join( ' ', @tokens ) . ";\n"; } ## end foreach my $line (@lines) # Join into the complete code block return join( '', @code ); } ## end sub dsl2code 1;