Stop the analysis pass in Loopy's redraw routine from being
[sgt/puzzles] / mkfiles.pl
index 796547a..625b9ab 100755 (executable)
@@ -17,6 +17,7 @@
 #  - special-define objects (foo.o[PREPROCSYMBOL]) are not
 #    supported in the mac or vcproj makefiles.
 
+use warnings;
 use IO::Handle;
 use Cwd;
 
@@ -49,21 +50,29 @@ $project_name = "project"; # this is a good enough default
 @allobjs = (); # all object file names
 
 readinput: while (1) {
+  $in = $filestack[$#filestack];
   while (not defined ($_ = <$in>)) {
-    close $in;
+    close $filestack[$#filestack];
+    pop @filestack;
     last readinput if 0 == scalar @filestack;
-    $in = pop @filestack;
+    $in = $filestack[$#filestack];
   }
-
   chomp;
-  split;
+  @_ = split;
 
-  # Skip comments (unless the comments belong, for example because
-  # they're part of a diversion).
-  next if /^\s*#/ and !defined $divert;
+  # If we're gathering help text, keep doing so.
+  if (defined $divert) {
+      if ((defined $_[0]) && $_[0] eq "!end") {
+         $divert = undef;
+      } else {
+         ${$divert} .= "$_\n";
+      }
+      next;
+  }
+  # Skip comments and blank lines.
+  next if /^\s*#/ or scalar @_ == 0;
 
   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; }
   if ($_[0] eq "!srcdir") { push @srcdirs, $_[1]; next; }
   if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
@@ -87,13 +96,8 @@ readinput: while (1) {
          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.
-  next if scalar @_ == 0;
 
   # Now we have an ordinary line. See if it's an = line, a : line
   # or a + line.
@@ -206,7 +210,7 @@ foreach $i (@allobjs) {
 foreach $i (@prognames) {
   ($prog, $type) = split ",", $i;
   # Strip duplicate object names.
-  $prev = undef;
+  $prev = '';
   @list = grep { $status = ($prev ne $_); $prev=$_; $status }
           sort @{$programs{$i}};
   $programs{$i} = [@list];
@@ -238,7 +242,6 @@ foreach $i (@prognames) {
 while (scalar @scanlist > 0) {
   $file = shift @scanlist;
   next if defined $further{$file}; # skip if we've already done it
-  $resource = ($file =~ /\.rc$/ ? 1 : 0);
   $further{$file} = [];
   $dirfile = &findfile($file);
   open IN, "$dirfile" or die "unable to open source file $file\n";
@@ -267,7 +270,7 @@ foreach $i (keys %depends) {
   while (scalar @scanlist > 0) {
     $file = shift @scanlist;
     foreach $j (@{$further{$file}}) {
-      if ($dep{$j} != 1) {
+      if (!$dep{$j}) {
         $dep{$j} = 1;
         push @{$depends{$i}}, $j;
         push @scanlist, $j;
@@ -284,7 +287,7 @@ sub mfval($) {
     # Returns true if the argument is a known makefile type. Otherwise,
     # prints a warning and returns false;
     if (grep { $type eq $_ }
-       ("vc","vcproj","cygwin","borland","lcc","gtk","mpw","nestedvm","osx","wce")) {
+       ("vc","vcproj","cygwin","borland","lcc","gtk","mpw","nestedvm","osx","wce","gnustep")) {
            return 1;
        }
     warn "$.:unknown makefile type '$type'\n";
@@ -296,7 +299,8 @@ sub mfval($) {
 sub dirpfx {
     my ($path) = shift @_;
     my ($sep) = shift @_;
-    my $ret = "", $i;
+    my $ret = "";
+    my $i;
     while (($i = index $path, $sep) >= 0) {
        $path = substr $path, ($i + length $sep);
        $ret .= "..$sep";
@@ -350,6 +354,7 @@ sub objects {
   my ($prog, $otmpl, $rtmpl, $ltmpl, $prefix, $dirsep) = @_;
   my @ret;
   my ($i, $x, $y);
+  ($otmpl, $rtmpl, $ltmpl) = map { defined $_ ? $_ : "" } ($otmpl, $rtmpl, $ltmpl);
   @ret = ();
   foreach $ii (@{$programs{$prog}}) {
     $i = $objname{$ii};
@@ -384,7 +389,8 @@ sub special {
 
 sub splitline {
   my ($line, $width, $splitchar) = @_;
-  my ($result, $len);
+  my $result = "";
+  my $len;
   $len = (defined $width ? $width : 76);
   $splitchar = (defined $splitchar ? $splitchar : '\\');
   while (length $line > $len) {
@@ -400,7 +406,8 @@ sub splitline {
 sub deps {
   my ($otmpl, $rtmpl, $prefix, $dirsep, $depchar, $splitchar) = @_;
   my ($i, $x, $y);
-  my @deps, @ret;
+  my @deps;
+  my @ret;
   @ret = ();
   $depchar ||= ':';
   foreach $ii (sort keys %depends) {
@@ -521,7 +528,7 @@ if (defined $makefiles{'cygwin'}) {
       }
     }
     print "\n";
-    print $makefile_extra{'cygwin'};
+    print $makefile_extra{'cygwin'} || "";
     print "\nclean:\n".
     "\trm -f *.o *.exe *.res.o *.map\n".
     "\n";
@@ -572,7 +579,7 @@ if (defined $makefiles{'borland'}) {
     print "\n\n";
     foreach $p (&prognames("G:C")) {
       ($prog, $type) = split ",", $p;
-      $objstr = &objects($p, "X.obj", "X.res", undef);
+      $objstr =  &objects($p, "X.obj", "X.res", undef);
       print &splitline("$prog.exe: " . $objstr . " $prog.rsp"), "\n";
       my $ap = ($type eq "G") ? "-aa" : "-ap";
       print "\tilink32 $ap -Gn -L\$(BCB)\\lib \@$prog.rsp\n\n";
@@ -621,7 +628,7 @@ if (defined $makefiles{'borland'}) {
       }
     }
     print "\n";
-    print $makefile_extra{'borland'};
+    print $makefile_extra{'borland'} || "";
     print "\nclean:\n".
     "\t-del *.obj\n".
     "\t-del *.exe\n".
@@ -654,7 +661,7 @@ if (defined $makefiles{'vc'}) {
       "MAKEFILE = Makefile.vc\n".
       "\n".
       "# C compilation flags\n".
-      "CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401\n".
+      "CFLAGS = /nologo /W3 /O1 /D_WINDOWS /D_WIN32_WINDOWS=0x401 /DWINVER=0x401 /I.\n".
       "LFLAGS = /incremental:no /fixed\n".
       "\n";
     print &splitline("all:" . join "", map { " $_.exe" } &progrealnames("G:C"));
@@ -697,7 +704,7 @@ if (defined $makefiles{'vc'}) {
        }
     }
     print "\n";
-    print $makefile_extra{'vc'};
+    print $makefile_extra{'vc'} || "";
     print "\nclean: tidy\n".
       "\t-del *.exe\n\n".
       "tidy:\n".
@@ -805,7 +812,7 @@ if (defined $makefiles{'wce'}) {
        }
     }
     print "\n";
-    print $makefile_extra{'wce'};
+    print $makefile_extra{'wce'} || "";
     print "\nclean: tidy\n".
       "\t-del *.exe\n\n".
       "tidy:\n".
@@ -1111,8 +1118,8 @@ if (defined $makefiles{'gtk'}) {
     &splitline("CFLAGS := -O2 -Wall -Werror -ansi -pedantic -g " .
               (join " ", map {"-I$dirpfx$_"} @srcdirs) .
               " `\$(GTK_CONFIG) --cflags` \$(CFLAGS)")."\n".
-    "XLDFLAGS = `\$(GTK_CONFIG) --libs`\n".
-    "ULDFLAGS =#\n".
+    "XLIBS = `\$(GTK_CONFIG) --libs` -lm\n".
+    "ULIBS = -lm#\n".
     "INSTALL=install\n",
     "INSTALL_PROGRAM=\$(INSTALL)\n",
     "INSTALL_DATA=\$(INSTALL)\n",
@@ -1123,15 +1130,16 @@ if (defined $makefiles{'gtk'}) {
     "mandir=\$(prefix)/man\n",
     "man1dir=\$(mandir)/man1\n",
     "\n";
-    print &splitline("all:" . join "", map { " $_" } &progrealnames("X:U"));
+    print &splitline("all:" . join "", map { " \$(BINPREFIX)$_" }
+                     &progrealnames("X:U"));
     print "\n\n";
     foreach $p (&prognames("X:U")) {
       ($prog, $type) = split ",", $p;
       $objstr = &objects($p, "X.o", undef, undef);
-      print &splitline($prog . ": " . $objstr), "\n";
+      print &splitline("\$(BINPREFIX)" . $prog . ": " . $objstr), "\n";
       $libstr = &objects($p, undef, undef, "-lX");
-      print &splitline("\t\$(CC)" . $mw . " \$(${type}LDFLAGS) -o \$@ " .
-                       $objstr . " $libstr", 69), "\n\n";
+      print &splitline("\t\$(CC) -o \$@ $objstr $libstr \$(XLFLAGS) \$(${type}LIBS)", 69),
+         "\n\n";
     }
     foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
       print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
@@ -1141,9 +1149,9 @@ if (defined $makefiles{'gtk'}) {
          " -c \$< -o \$\@\n";
     }
     print "\n";
-    print $makefile_extra{'gtk'};
+    print $makefile_extra{'gtk'} || "";
     print "\nclean:\n".
-    "\trm -f *.o". (join "", map { " $_" } &progrealnames("X:U")) . "\n";
+    "\trm -f *.o". (join "", map { " \$(BINPREFIX)$_" } &progrealnames("X:U")) . "\n";
     select STDOUT; close OUT;
 }
 
@@ -1339,7 +1347,7 @@ if (defined $makefiles{'lcc'}) {
       }
     }
     print "\n";
-    print $makefile_extra{'lcc'};
+    print $makefile_extra{'lcc'} || "";
     print "\nclean:\n".
     "\t-del *.obj\n".
     "\t-del *.exe\n".
@@ -1380,7 +1388,7 @@ if (defined $makefiles{'nestedvm'}) {
       $objstr =~ s/gtk\.o/nestedvm\.o/g;
       print &splitline($prog . ".mips: " . $objstr), "\n";
       $libstr = &objects($p, undef, undef, "-lX");
-      print &splitline("\t\$(CC)" . $mw . " \$(${type}LDFLAGS) -o \$@ " .
+      print &splitline("\t\$(CC) \$(${type}LDFLAGS) -o \$@ " .
                        $objstr . " $libstr -lm", 69), "\n\n";
     }
     foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
@@ -1395,7 +1403,7 @@ if (defined $makefiles{'nestedvm'}) {
          " -c \$< -o \$\@\n";
     }
     print "\n";
-    print $makefile_extra{'nestedvm'};
+    print $makefile_extra{'nestedvm'} || "";
     print "\nclean:\n".
     "\trm -rf *.o *.mips *.class *.html *.jar org applet.manifest\n";
     select STDOUT; close OUT;
@@ -1404,7 +1412,7 @@ if (defined $makefiles{'nestedvm'}) {
 if (defined $makefiles{'osx'}) {
     $mftyp = 'osx';
     $dirpfx = &dirpfx($makefiles{'osx'}, "/");
-    @osxarchs = ('ppc', 'i386');
+    @osxarchs = ('i386');
 
     ##-- Mac OS X makefile
     open OUT, ">$makefiles{'osx'}"; select OUT;
@@ -1423,9 +1431,9 @@ if (defined $makefiles{'osx'}) {
               (join " ", map {"-I$dirpfx$_"} @srcdirs))."\n".
     "LDFLAGS = -framework Cocoa\n".
     &splitline("all:" . join "", map { " $_" } &progrealnames("MX:U")) .
-    "\n" .
-    $makefile_extra{'osx'} .
-    "\n".
+    "\n";
+    print $makefile_extra{'osx'} || "";
+    print "\n".
     ".SUFFIXES: .o .c .m\n".
     "\n";
     print "\n\n";
@@ -1453,7 +1461,7 @@ if (defined $makefiles{'osx'}) {
       foreach $arch (@osxarchs) {
        $objstr = &objects($p, "X.${arch}.o", undef, undef);
        print &splitline("${prog}.${arch}.bin: " . $objstr), "\n";
-       print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=10.3 \$(LDFLAGS) -o \$@ " .
+       print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=10.4 \$(LDFLAGS) -o \$@ " .
                        $objstr . " $libstr", 69), "\n\n";
        $archbins .= " ${prog}.${arch}.bin";
       }
@@ -1468,7 +1476,7 @@ if (defined $makefiles{'osx'}) {
       foreach $arch (@osxarchs) {
        $objstr = &objects($p, "X.${arch}.o", undef, undef);
        print &splitline("${prog}.${arch}: " . $objstr), "\n";
-       print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=10.3 \$(ULDFLAGS) -o \$@ " .
+       print &splitline("\t\$(CC) -arch ${arch} -mmacosx-version-min=10.4 \$(ULDFLAGS) -o \$@ " .
                        $objstr . " $libstr", 69), "\n\n";
        $archbins .= " ${prog}.${arch}";
       }
@@ -1481,10 +1489,10 @@ if (defined $makefiles{'osx'}) {
             "\n";
         $deflist = join "", map { " -D$_" } @{$d->{defs}};
         if ($d->{deps}->[0] =~ /\.m$/) {
-         print "\t\$(CC) -arch $arch -mmacosx-version-min=10.3 -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
+         print "\t\$(CC) -arch $arch -mmacosx-version-min=10.4 -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS)".
              " \$(XFLAGS)$deflist -c \$< -o \$\@\n";
         } else {
-         print "\t\$(CC) -arch $arch -mmacosx-version-min=10.3 \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
+         print "\t\$(CC) -arch $arch -mmacosx-version-min=10.4 \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
              " -c \$< -o \$\@\n";
         }
       }
@@ -1494,3 +1502,90 @@ if (defined $makefiles{'osx'}) {
     "\trm -rf *.app\n";
     select STDOUT; close OUT;
 }
+
+if (defined $makefiles{'gnustep'}) {
+    $mftyp = 'gnustep';
+    $dirpfx = &dirpfx($makefiles{'gnustep'}, "/");
+
+    ##-- GNUstep makefile (use with 'gs_make -f Makefile.gnustep')
+
+    # This is a pretty evil way to do things. In an ideal world, I'd
+    # use the approved GNUstep makefile mechanism which just defines a
+    # variable or two saying what source files go into what binary and
+    # then includes application.make. Unfortunately, that has the
+    # automake-ish limitation that it doesn't let you choose different
+    # command lines for each object, so I can't arrange for all those
+    # files with -DTHIS and -DTHAT to Just Work.
+    #
+    # A simple if ugly fix would be to have mkfiles.pl construct a
+    # directory full of stub C files of the form '#define thing',
+    # '#include "real_source_file"', and then reference those in this
+    # makefile. That would also make it easy to build a proper
+    # automake makefile.
+    open OUT, ">$makefiles{'gnustep'}"; select OUT;
+    print
+    "# Makefile for $project_name under GNUstep.\n".
+    "#\n# This file was created by `mkfiles.pl' from the `Recipe' file.\n".
+    "# DO NOT EDIT THIS FILE DIRECTLY; edit Recipe or mkfiles.pl instead.\n";
+    # gcc command line option is -D not /D
+    ($_ = $help) =~ s/=\/D/=-D/gs;
+    print $_;
+    print
+    "NEEDS_GUI=yes\n".
+    "include \$(GNUSTEP_MAKEFILES)/common.make\n".
+    "include \$(GNUSTEP_MAKEFILES)/rules.make\n".
+    "include \$(GNUSTEP_MAKEFILES)/Instance/rules.make\n".
+    "\n".
+    &splitline("all::" . join "", map { " $_" } &progrealnames("MX:U")) .
+    "\n";
+    print $makefile_extra{'gnustep'} || "";
+    print "\n".
+    ".SUFFIXES: .o .c .m\n".
+    "\n";
+    print "\n\n";
+    foreach $p (&prognames("MX")) {
+      ($prog, $type) = split ",", $p;
+      $icon = &special($p, ".icns");
+      $infoplist = &special($p, "info.plist");
+      print "${prog}.app:\n\tmkdir -p \$\@\n";
+      $targets = "${prog}.app ${prog}.app/$prog";
+      if (defined $icon) {
+       print "${prog}.app/Resources: ${prog}.app\n\tmkdir -p \$\@\n";
+       print "${prog}.app/Resources/${prog}.icns: ${prog}.app/Resources $icon\n\tcp $icon \$\@\n";
+       $targets .= " ${prog}.app/Resources/${prog}.icns";
+      }
+      if (defined $infoplist) {
+       print "${prog}.app/Info.plist: ${prog}.app $infoplist\n\tcp $infoplist \$\@\n";
+       $targets .= " ${prog}.app/Info.plist";
+      }
+      $targets .= " \$(${prog}_extra)";
+      print &splitline("${prog}: $targets", 69) . "\n\n";
+      $libstr = &objects($p, undef, undef, "-lX");
+      $objstr = &objects($p, "X.o", undef, undef);
+      print &splitline("${prog}.app/$prog: " . $objstr), "\n";
+      print &splitline("\t\$(CC) \$(ALL_LDFLAGS) -o \$@ " . $objstr . " \$(ALL_LIB_DIRS) $libstr \$(ALL_LIBS)", 69), "\n\n";
+    }
+    foreach $p (&prognames("U")) {
+      ($prog, $type) = split ",", $p;
+      $libstr = &objects($p, undef, undef, "-lX");
+      $objstr = &objects($p, "X.o", undef, undef);
+      print &splitline("${prog}: " . $objstr), "\n";
+      print &splitline("\t\$(CC) \$(ULDFLAGS) -o \$@ " . $objstr . " $libstr", 69), "\n\n";
+    }
+    foreach $d (&deps("X.o", undef, $dirpfx, "/")) {
+      print &splitline(sprintf("%s: %s", $d->{obj}, join " ", @{$d->{deps}})),
+      "\n";
+      $deflist = join "", map { " -D$_" } @{$d->{defs}};
+      if ($d->{deps}->[0] =~ /\.m$/) {
+        print "\t\$(CC) -DGNUSTEP \$(ALL_OBJCFLAGS) \$(COMPAT) \$(FWHACK) \$(OBJCFLAGS)".
+                " \$(XFLAGS)$deflist -c \$< -o \$\@\n";
+      } else {
+        print "\t\$(CC) \$(ALL_CFLAGS) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS)$deflist" .
+              " -c \$< -o \$\@\n";
+      }
+    }
+    print "\nclean::\n".
+    "\trm -f *.o ". (join " ", &progrealnames("U")) . "\n".
+    "\trm -rf *.app\n";
+    select STDOUT; close OUT;
+}