41 # read through the rom_content_csv looking for direct instructions |
41 # read through the rom_content_csv looking for direct instructions |
42 my %stem_substitutions; |
42 my %stem_substitutions; |
43 my %rom_origins; |
43 my %rom_origins; |
44 my %deletions; |
44 my %deletions; |
45 my %must_have; |
45 my %must_have; |
|
46 my %check_import_details; |
46 foreach my $line (@rom_content) |
47 foreach my $line (@rom_content) |
47 { |
48 { |
48 my ($romfile,$hostfile,$ibyfile,$package,$cmd,@rest) = split /,/, $line; |
49 my ($romfile,$hostfile,$ibyfile,$package,$cmd,@rest) = split /,/, $line; |
49 |
50 |
50 $rom_origins{$romfile} = "$ibyfile,$package"; |
51 $rom_origins{$romfile} = "$ibyfile,$package"; |
51 next if ($cmd eq ""); |
52 next if ($cmd eq ""); |
52 |
53 |
53 $cmd = lc $cmd; |
54 $cmd = lc $cmd; |
54 if ($cmd eq "stem") |
55 if ($cmd eq "slim") |
55 { |
56 { |
|
57 $check_import_details{$romfile} = ""; |
56 $stem_substitutions{$romfile} = $hostfile; |
58 $stem_substitutions{$romfile} = $hostfile; |
57 $must_have{$romfile} = 1; |
59 $must_have{$romfile} = 1; |
58 next; |
60 next; |
59 } |
61 } |
|
62 |
|
63 if ($cmd eq "stem") |
|
64 { |
|
65 $stem_substitutions{$romfile} = $hostfile; |
|
66 $must_have{$romfile} = 1; |
|
67 next; |
|
68 } |
60 |
69 |
61 if ($cmd eq "out") |
70 if ($cmd eq "out") |
62 { |
71 { |
63 # print STDERR "Deletion request for >$romfile<\n"; |
72 # print STDERR "Deletion request for >$romfile<\n"; |
64 $deletions{$romfile} = "out"; |
73 $deletions{$romfile} = "out"; |
70 $must_have{$romfile} = 1; |
79 $must_have{$romfile} = 1; |
71 next; |
80 next; |
72 } |
81 } |
73 } |
82 } |
74 |
83 |
75 printf STDERR "%d in (including %d stem), %d out\n", |
84 printf STDERR "%d in (including %d slim and %d stem), %d out\n", |
76 scalar keys %must_have, |
85 scalar keys %must_have, |
77 scalar keys %stem_substitutions, |
86 scalar keys %check_import_details, |
|
87 (scalar keys %stem_substitutions) - (scalar keys %check_import_details), |
78 scalar keys %deletions; |
88 scalar keys %deletions; |
79 |
89 |
80 # read static dependencies file |
90 # read static dependencies file |
81 my %exe_to_romfile; # exe -> original romfile |
91 my %exe_to_romfile; # exe -> original romfile |
82 my %exe_dependencies; # exe -> list of romfile |
92 my %exe_dependencies; # exe -> list of romfile |
83 my %exe_prerequisites; # exe -> list of exe |
93 my %exe_prerequisites; # exe -> list of exe |
|
94 my %exe_ordinals; # exe -> list of valid ordinals |
84 my %lc_romfiles; |
95 my %lc_romfiles; |
85 |
96 |
86 my $line; |
97 my $line; |
87 open STATIC_DEPENDENCIES, "<$static_dependencies_txt" or die ("Cannot read $static_dependencies_txt: $!\n"); |
98 open STATIC_DEPENDENCIES, "<$static_dependencies_txt" or die ("Cannot read $static_dependencies_txt: $!\n"); |
88 while ($line = <STATIC_DEPENDENCIES>) |
99 while ($line = <STATIC_DEPENDENCIES>) |
112 |
123 |
113 my @prerequisite_exes = (); |
124 my @prerequisite_exes = (); |
114 foreach my $prerequisite (split /:/,$stuff) |
125 foreach my $prerequisite (split /:/,$stuff) |
115 { |
126 { |
116 next if ($prerequisite =~ /^sid=/); # not a real file |
127 next if ($prerequisite =~ /^sid=/); # not a real file |
|
128 if ($prerequisite =~ /^exports=(.*)$/) |
|
129 { |
|
130 my $ordinals = $1; |
|
131 if (defined $check_import_details{$romfile}) |
|
132 { |
|
133 $exe_ordinals{$romexe} = $ordinals; |
|
134 } |
|
135 next; |
|
136 } |
117 $prerequisite =~ s/^sys.bin.//; # remove leading sys/bin, if present |
137 $prerequisite =~ s/^sys.bin.//; # remove leading sys/bin, if present |
118 if ($prerequisite !~ /\\/) |
138 if ($prerequisite !~ /\\/) |
119 { |
139 { |
120 my $exe = lc $prerequisite; |
140 my $exe = lc $prerequisite; |
121 $exe =~ s/\[\S+\]//; # ignore the UIDs for now |
141 $exe =~ s/\[\S+\]//; # ignore the UIDs for now |
122 |
142 |
123 push @prerequisite_exes, $exe; |
143 push @prerequisite_exes, $exe; |
|
144 $exe =~ s/@.*$//; # remove the ordinals, though they remain in the prerequisite exes |
|
145 |
124 if (!defined $exe_dependencies{$exe}) |
146 if (!defined $exe_dependencies{$exe}) |
125 { |
147 { |
126 my @dependents = ($romfile); |
148 my @dependents = ($romfile); |
127 $exe_dependencies{$exe} = \@dependents; |
149 $exe_dependencies{$exe} = \@dependents; |
128 } |
150 } |
177 } |
199 } |
178 } |
200 } |
179 |
201 |
180 if (0) |
202 if (0) |
181 { |
203 { |
182 foreach my $exe ("libopenvg.dll", "libopenvg_sw.dll", "backend.dll") |
204 foreach my $exe ("libopenvg.dll", "libopenvg_sw.dll", "backend.dll", "qtgui.dll") |
183 { |
205 { |
184 printf STDERR "Dependents of %s = %s\n", $exe, join(", ", @{$exe_dependencies{$exe}}); |
206 printf STDERR "Dependents of %s = %s\n", $exe, join(", ", @{$exe_dependencies{$exe}}); |
185 } |
207 } |
186 } |
208 } |
187 |
209 |
188 # process the "out" commands to recursively expand the deletions |
|
189 |
210 |
190 my @details; |
211 my @details; |
191 sub print_detail($) |
212 sub print_detail($) |
192 { |
213 { |
193 my ($message) = @_; |
214 my ($message) = @_; |
194 push @details, $message; |
215 push @details, $message; |
195 print STDERR $message, "\n"; |
216 print STDERR $message, "\n"; |
196 } |
217 } |
|
218 |
|
219 # check the dependents of "slim" DLLs to see if they get eliminated by missing ordinals |
|
220 |
|
221 sub expand_list($$) |
|
222 { |
|
223 my ($hashref, $list) = @_; |
|
224 foreach my $range (split /\./, $list) |
|
225 { |
|
226 if ($range =~ /^(\d+)-(\d+)$/) |
|
227 { |
|
228 foreach my $ordinal ($1 .. $2) |
|
229 { |
|
230 $$hashref{$ordinal} = 1; |
|
231 } |
|
232 } |
|
233 else |
|
234 { |
|
235 $$hashref{$range} = 1; |
|
236 } |
|
237 } |
|
238 } |
|
239 sub check_list($$) |
|
240 { |
|
241 my ($hashref, $list) = @_; |
|
242 foreach my $range (split /\./, $list) |
|
243 { |
|
244 if ($range =~ /^(\d+)-(\d+)$/) |
|
245 { |
|
246 foreach my $ordinal ($1 .. $2) |
|
247 { |
|
248 if (!defined $$hashref{$ordinal}) |
|
249 { |
|
250 return "Missing ordinal $ordinal"; |
|
251 } |
|
252 } |
|
253 } |
|
254 else |
|
255 { |
|
256 return "Missing ordinal $range" if (!defined $$hashref{$range}); |
|
257 } |
|
258 } |
|
259 return "OK"; |
|
260 } |
|
261 |
|
262 |
|
263 foreach my $romexe (keys %exe_ordinals) |
|
264 { |
|
265 my $exported_ordinals = $exe_ordinals{$romexe}; |
|
266 my %exports; |
|
267 expand_list(\%exports, $exported_ordinals); |
|
268 my $namelength = length($romexe); |
|
269 foreach my $dependent (@{$exe_dependencies{$romexe}}) |
|
270 { |
|
271 next if (defined $deletions{$dependent}); # already |
|
272 |
|
273 if ($dependent =~ /^sys.bin.(.*)$/i) |
|
274 { |
|
275 my $depexe = lc $1; |
|
276 my $imports; |
|
277 foreach my $prerequisite (@{$exe_prerequisites{$depexe}}) |
|
278 { |
|
279 if (substr($prerequisite, 0, $namelength) eq $romexe) |
|
280 { |
|
281 $imports = substr($prerequisite, $namelength+1); # skip name and "@" |
|
282 last; |
|
283 } |
|
284 } |
|
285 if (!defined $imports) |
|
286 { |
|
287 printf STDERR "Failed to find ordinals imported from %s by %s (in %s)\n", |
|
288 $romexe, $dependent, join(":",@{$exe_prerequisites{$depexe}}); |
|
289 next; |
|
290 } |
|
291 my $compatible = check_list(\%exports,$imports); |
|
292 if ($compatible ne "OK") |
|
293 { |
|
294 $deletions{$dependent} = "$romexe $compatible"; |
|
295 # print_detail("Deleting $dependent because of slimmed $romexe ($compatible)"); |
|
296 } |
|
297 } |
|
298 } |
|
299 } |
|
300 |
|
301 # process the "out" commands to recursively expand the deletions |
197 |
302 |
198 my @problems; # list of romtrails which will be a problem |
303 my @problems; # list of romtrails which will be a problem |
199 sub delete_dependents($$$) |
304 sub delete_dependents($$$) |
200 { |
305 { |
201 my ($romtrail,$original_reason,$listref) = @_; |
306 my ($romtrail,$original_reason,$listref) = @_; |
244 my @delete_cmds = sort keys %deletions; |
349 my @delete_cmds = sort keys %deletions; |
245 foreach my $romfile (@delete_cmds) |
350 foreach my $romfile (@delete_cmds) |
246 { |
351 { |
247 push @details, "", "===Deleting $romfile", ""; |
352 push @details, "", "===Deleting $romfile", ""; |
248 |
353 |
|
354 my $reason = $deletions{$romfile}; |
249 delete $deletions{$romfile}; # so that delete_dependents will iterate properly |
355 delete $deletions{$romfile}; # so that delete_dependents will iterate properly |
250 my @delete_list = ("$romfile\tout"); |
356 my @delete_list = ("$romfile\t$reason"); |
251 while (scalar @delete_list > 0) |
357 while (scalar @delete_list > 0) |
252 { |
358 { |
253 my $next_victim = shift @delete_list; |
359 my $next_victim = shift @delete_list; |
254 delete_dependents($next_victim, $romfile, \@delete_list); |
360 delete_dependents($next_victim, $romfile, \@delete_list); |
255 } |
361 } |
461 { |
568 { |
462 print FILE $line, "\n"; |
569 print FILE $line, "\n"; |
463 } |
570 } |
464 |
571 |
465 print FILE "\n====\n"; |
572 print FILE "\n====\n"; |
|
573 printf FILE "Minimum ROM now has %d exes\n", scalar keys %must_have_exes; |
466 foreach my $deletion_root (sort {$b <=> $a} @deletion_roots) |
574 foreach my $deletion_root (sort {$b <=> $a} @deletion_roots) |
467 { |
575 { |
468 my ($count,$exe) = split /\s+/, $deletion_root; |
576 my ($count,$exe) = split /\s+/, $deletion_root; |
469 printf FILE "Remove %d files by deleting %s (%s)\n", $count, $exe, $rom_origins{$exe_to_romfile{$exe}}; |
577 printf FILE "Remove %d files by deleting %s (%s)\n", $count, $exe, $rom_origins{$exe_to_romfile{$exe}}; |
470 } |
578 } |