tools/filter_obyfile.pl
changeset 80 3ab0df073c86
parent 78 7271390ae2c2
child 99 e23a8d7ea8bb
equal deleted inserted replaced
79:26cde9838d22 80:3ab0df073c86
    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>)
    94 	
   105 	
    95 	if (defined $stem_substitutions{$romfile})
   106 	if (defined $stem_substitutions{$romfile})
    96 		{
   107 		{
    97 		if ($hostfile !~ /\/stem_/)
   108 		if ($hostfile !~ /\/stem_/)
    98 			{
   109 			{
    99 			print STDERR "Ignoring dependencies of $hostfile because of stem substitution of $romfile\n";
   110 			# print STDERR "Ignoring dependencies of $hostfile because of stem substitution of $romfile\n";
   100 			next;
   111 			next;
   101 			}
   112 			}
   102 		}
   113 		}
   103 
   114 
   104 	$lc_romfiles{lc $romfile} = $romfile;
   115 	$lc_romfiles{lc $romfile} = $romfile;
   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 		}
   377 		# printf STDERR "$exe has no prerequisites to be marked!\n";
   483 		# printf STDERR "$exe has no prerequisites to be marked!\n";
   378 		return;
   484 		return;
   379 		}
   485 		}
   380 	foreach my $prerequisite (@{$exe_prerequisites{$exe}})
   486 	foreach my $prerequisite (@{$exe_prerequisites{$exe}})
   381 		{
   487 		{
       
   488 		$prerequisite =~ s/@.*$//;	# remove any ordinal information
   382 		mark_prerequisites($prerequisite);
   489 		mark_prerequisites($prerequisite);
   383 		}
   490 		}
   384 	}
   491 	}
   385 
   492 
   386 foreach my $romfile (keys %must_have)
   493 foreach my $romfile (keys %must_have)
   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 		}