X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/84c79161754633fd1a848abcd05ca6e6cfae12c4..8379e6f510749e24caa8d52b1aaae6bc5877bf91:/mkfiles.pl diff --git a/mkfiles.pl b/mkfiles.pl index b93e4fa..a107737 100755 --- a/mkfiles.pl +++ b/mkfiles.pl @@ -17,16 +17,19 @@ # - 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 () { +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 () { 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 () { $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 () { $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 () { $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; }