+
+# Now retrieve the complete list of objects and resource files, and
+# construct dependency data for them. While we're here, expand the
+# object list for each program, and complain if its type isn't set.
+@prognames = sort keys %programs;
+%depends = ();
+@scanlist = ();
+foreach $i (@prognames) {
+ if (!defined $types{$i}) { die "type not set for program $i\n"; }
+ # Strip duplicate object names.
+ $prev = undef;
+ @list = grep { $status = ($prev ne $_); $prev=$_; $status }
+ sort @{$programs{$i}};
+ $programs{$i} = [@list];
+ foreach $j (@list) {
+ # Dependencies for "x" start with "x.c".
+ # Dependencies for "x.res" start with "x.rc".
+ # Both types of file are pushed on the list of files to scan.
+ # Libraries (.lib) don't have dependencies at all.
+ if ($j =~ /^(.*)\.res$/) {
+ $file = "$1.rc";
+ $depends{$j} = [$file];
+ push @scanlist, $file;
+ } elsif ($j =~ /\.lib$/) {
+ # libraries don't have dependencies
+ } else {
+ $file = "$j.c";
+ $depends{$j} = [$file];
+ push @scanlist, $file;
+ }
+ }
+}
+
+# Scan each file on @scanlist and find further inclusions.
+# Inclusions are given by lines of the form `#include "otherfile"'
+# (system headers are automatically ignored by this because they'll
+# be given in angle brackets). Files included by this method are
+# added back on to @scanlist to be scanned in turn (if not already
+# done).
+#
+# Resource scripts (.rc) can also include a file by means of a line
+# ending `ICON "filename"'. Files included by this method are not
+# added to @scanlist because they can never include further files.
+#
+# In this pass we write out a hash %further which maps a source
+# file name into a listref containing further source file names.
+
+%further = ();
+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} = [];
+ open IN, $file or die "unable to open source file $file\n";
+ while (<IN>) {
+ chomp;
+ /^\s*#include\s+\"([^\"]+)\"/ and do {
+ push @{$further{$file}}, $1;
+ push @scanlist, $1;
+ next;
+ };
+ /ICON\s+\"([^\"]+)\"\s*$/ and do {
+ push @{$further{$file}}, $1;
+ next;
+ }
+ }
+ close IN;