Minimal (i.e., lame) update to Loopy documentation to match reality -- it's
[sgt/puzzles] / mkfiles.pl
index 1421a92..a107737 100755 (executable)
 #  - special-define objects (foo.o[PREPROCSYMBOL]) are not
 #    supported in the mac or vcproj makefiles.
 
-use FileHandle;
+use IO::Handle;
 use Cwd;
 
-open IN, "Recipe" or do {
+@filestack = ();
+$in = new IO::Handle;
+open $in, "Recipe" or do {
     # We want to deal correctly with being run from one of the
     # subdirs in the source tree. So if we can't find Recipe here,
     # try one level up.
     chdir "..";
-    open IN, "Recipe" or die "unable to open Recipe file\n";
+    open $in, "Recipe" or die "unable to open Recipe file\n";
 };
+push @filestack, $in;
 
 # HACK: One of the source files in `charset' is auto-generated by
 # sbcsgen.pl. We need to generate that _now_, before attempting
@@ -45,13 +48,20 @@ $project_name = "project"; # this is a good enough default
 
 @allobjs = (); # all object file names
 
-while (<IN>) {
+readinput: while (1) {
+  while (not defined ($_ = <$in>)) {
+    close $in;
+    last readinput if 0 == scalar @filestack;
+    $in = pop @filestack;
+  }
+
+  chomp;
+  split;
+
   # Skip comments (unless the comments belong, for example because
   # they're part of a diversion).
   next if /^\s*#/ and !defined $divert;
 
-  chomp;
-  split;
   if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = \$help; next; }
   if ($_[0] eq "!end") { $divert = undef; next; }
   if ($_[0] eq "!name") { $project_name = $_[1]; next; }
@@ -59,13 +69,27 @@ while (<IN>) {
   if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
   if ($_[0] eq "!specialobj" and &mfval($_[1])) { $specialobj{$_[1]}->{$_[2]} = 1; next;}
   if ($_[0] eq "!begin") {
-      if (&mfval($_[1])) {
+      if ($_[1] =~ /^>(.*)/) {
+         $divert = \$auxfiles{$1};
+      } elsif (&mfval($_[1])) {
          $divert = \$makefile_extra{$_[1]};
-      } else {
-         $divert = \$dummy;
       }
       next;
   }
+  if ($_[0] eq "!include") {
+      @newfiles = ();
+      for ($i = 1; $i <= $#_; $i++) {
+         push @newfiles, (sort glob $_[$i]);
+      }
+      for ($i = $#newfiles; $i >= 0; $i--) {
+         $file = $newfiles[$i];
+         $f = new IO::Handle;
+         open $f, "<$file" or die "unable to open include file '$file'\n";
+         push @filestack, $f;
+      }
+      $in = $filestack[$#filestack];
+      next;
+  }
   # If we're gathering help text, keep doing so.
   if (defined $divert) { ${$divert} .= "$_\n"; next; }
   # Ignore blank lines.
@@ -80,6 +104,11 @@ while (<IN>) {
     $prog = undef;
     die "$.: unexpected + line\n" if !defined $lastlistref;
   } elsif ($_[1] eq "=") {
+    $groups{$_[0]} = [];
+    $listref = $groups{$_[0]};
+    $prog = undef;
+    shift @objs; # eat the group name
+  } elsif ($_[1] eq "+=") {
     $groups{$_[0]} = [] if !defined $groups{$_[0]};
     $listref = $groups{$_[0]};
     $prog = undef;
@@ -89,7 +118,7 @@ while (<IN>) {
     $prog = $_[0];
     shift @objs; # eat the program name
   } else {
-    die "$.: unrecognised line type\n";
+    die "$.: unrecognised line type: '$_'\n";
   }
   shift @objs; # eat the +, the = or the :
 
@@ -113,7 +142,11 @@ while (<IN>) {
   $lastlistref = $listref;
 }
 
-close IN;
+foreach $aux (sort keys %auxfiles) {
+    open AUX, ">$aux";
+    print AUX $auxfiles{$aux};
+    close AUX;
+}
 
 # Find object file names with predefines (in square brackets after
 # the module name), and decide on actual object names for them.
@@ -325,7 +358,8 @@ sub splitline {
   $splitchar = (defined $splitchar ? $splitchar : '\\');
   while (length $line > $len) {
     $line =~ /^(.{0,$len})\s(.*)$/ or $line =~ /^(.{$len,}?\s(.*)$/;
-    $result .= $1 . " ${splitchar}\n\t\t";
+    $result .= $1;
+    $result .= " ${splitchar}\n\t\t" if $2 ne '';
     $line = $2;
     $len = 60;
   }
@@ -428,14 +462,6 @@ if (defined $makefiles{'cygwin'}) {
     "LDFLAGS = -mno-cygwin -s\n".
     &splitline("RCFLAGS = \$(RCINC) --define WIN32=1 --define _WIN32=1".
       " --define WINVER=0x0400 --define MINGW32_FIX=1")."\n".
-    "\n".
-    ".SUFFIXES:\n".
-    "\n".
-    "%.o: %.c\n".
-    "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
-    "\n".
-    "%.res.o: %.rc\n".
-    "\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) \$< \$\@\n".
     "\n";
     print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
     print "\n\n";
@@ -456,8 +482,8 @@ if (defined $makefiles{'cygwin'}) {
        print "\t\$(RC) \$(FWHACK) \$(RCFL) \$(RCFLAGS) \$< \$\@\n";
       } else {
        $deflist = join "", map { " -D$_" } @{$d->{defs}};
-       print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS)" .
-           " \$(CFLAGS)$deflist -c \$< -o \$\@\n";
+       print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS)" .
+           " \$(XFLAGS)$deflist -c \$< -o \$\@\n";
       }
     }
     print "\n";
@@ -555,7 +581,7 @@ if (defined $makefiles{'borland'}) {
       } else {
        $deflist = join "", map { " -D$_" } @{$d->{defs}};
        print &splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT)" .
-                        " \$(FWHACK) \$(XFLAGS) \$(CFLAGS)$deflist ".
+                        " \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist ".
                         (join " ", map {"-I$dirpfx$_"} @srcdirs) .
                         " /o$d->{obj} /c ".$d->{deps}->[0],69)."\n";
       }
@@ -632,7 +658,7 @@ if (defined $makefiles{'vc'}) {
              "-DWINVER=0x0400 ".$d->{deps}->[0]."\n";
        } else {
            $deflist = join "", map { " /D$_" } @{$d->{defs}};
-           print "\tcl \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS)$deflist".
+           print "\tcl \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist".
              " /c ".$d->{deps}->[0]." /Fo$d->{obj}\n";
        }
     }
@@ -969,7 +995,7 @@ if (defined $makefiles{'gtk'}) {
       print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
           "\n";
       $deflist = join "", map { " -D$_" } @{$d->{defs}};
-      print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS)$deflist" .
+      print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
          " -c \$< -o \$\@\n";
     }
     print "\n";
@@ -1166,8 +1192,8 @@ if (defined $makefiles{'lcc'}) {
        print &splitline("\tlrc \$(FWHACK) \$(RCFL) -r \$*.rc",69)."\n";
       } else {
        $deflist = join "", map { " -D$_" } @{$d->{defs}};
-       print &splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK) \$(XFLAGS)".
-                        " \$(CFLAGS)$deflist ".$d->{deps}->[0]." -o \$\@",69)."\n";
+       print &splitline("\tlcc -O -p6 \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
+                        " \$(XFLAGS)$deflist ".$d->{deps}->[0]." -o \$\@",69)."\n";
       }
     }
     print "\n";
@@ -1245,10 +1271,10 @@ if (defined $makefiles{'osx'}) {
           "\n";
       $deflist = join "", map { " -D$_" } @{$d->{defs}};
       if ($d->{deps}->[0] =~ /\.m$/) {
-       print "\t\$(CC) -x objective-c \$(COMPAT) \$(FWHACK) \$(XFLAGS)".
-           " \$(CFLAGS)$deflist -c \$< -o \$\@\n";
+       print "\t\$(CC) -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
+           " \$(XFLAGS)$deflist -c \$< -o \$\@\n";
       } else {
-       print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS)$deflist" .
+       print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
            " -c \$< -o \$\@\n";
       }
     }