The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# genmk95.pl - uses miniperl to generate a makefile that command.com will
#              understand given one that cmd.exe will understand

# Author: Benjamin K. Stuhl
# Date: 10-16-1999

# how it works:
#    dmake supports an alternative form for its recipes, called "group
#    recipes", in which all elements of a recipe are run with only one shell.
#    This program converts the standard dmake makefile.mk to one using group
#    recipes. This is done so that lines using && or || (which command.com
#    doesn't understand) may be split into two lines that will still be run
#    with one shell.

my ($filein, $fileout) = @ARGV;

open my $in, $filein or die "Error opening input file: $!\n";
open my $out, "> $fileout" or die "Error opening output file: $!\n";

print $out <<_EOH_;
# *** Warning: this file is autogenerated from $filein by $0 ***
# *** Do not edit this file - edit $filein instead           ***

_HOME_DIR := \$(PWD)

_EOH_

my $inrec = 0;

while (<$in>)
{
 chomp;
 if (/^[^#.\t][^#=]*?:(?:[^=]|$)/)
 {
    if (! $inrec)
    {
       print $out "$_\n";
       while (/\\\s*$/)
       {
          chomp($_ = <$in>);
          print $out "$_\n";
       }
       print $out "@[\n";
       $inrec = 1;
       next;
    }
    else {
       if (!/^\t/) {
           seek ($out, -4, 2);      # no recipe, so back up and undo grouping
                                    # should be -3, but MS has its CR/LF thing...
           $inrec = 0;
       }
       print $out "$_\n";
       next;
    }
 }
 if ((/^\s*$/ || /^[^#.\t][^#=]*?:/) && $inrec)
 {
    print $out "]\n";
    print $out "$_\n";
    $inrec = 0;
    next;
 }
 if (/^(.*?)(&&|\|\|)(.*)$/)  # two commands separated by && or ||
 {
    my ($one, $sep, $two) = ($1, $2, $3);
    $one =~ s/^\t(?:-(?!-))?\@?(.*?)$/\t$1/;   # no -,@ in group recipes
LINE_CONT:
    if ($two =~ /\\\s*$/)
    {
       chomp ($two .= "\n" . scalar <$in>);
       goto LINE_CONT;
    }
    s/^\s*// for ($one, $two);
    print $out "\t$one\n\t$two\n" if ($sep eq "&&");
    print $out "\t$one\n\tif errorlevel 1 $two\n" if ($sep eq "||");
    print $out "\tcd \$(_HOME_DIR)\n";
    next;
 }
     # fall through - no need for special handling
 s/^\t(?:-(?!-))?\@?(.*?)$/\t$1/;      # no -,@ in group recipes
 print $out "$_\n";
}
print $out "]\n" if ($inrec);

close $in or warn "Error closing \$in: $!\n";
close $out or warn "Error closing \$out: $!\n";