bc_tools/la_filter.pl
changeset 240 e662a2267ea5
parent 234 74890d706f0c
child 244 38294310f88b
equal deleted inserted replaced
239:d57b367400c0 240:e662a2267ea5
    12 #
    12 #
    13 # Description:
    13 # Description:
    14 #   This is a tool for filtering static BC libraries reports.
    14 #   This is a tool for filtering static BC libraries reports.
    15 
    15 
    16 use strict;
    16 use strict;
       
    17 use Getopt::Long;
    17 use XML::Simple;
    18 use XML::Simple;
    18 use File::Copy;
       
    19 use Tie::File;
    19 use Tie::File;
    20 use Data::Dumper;
       
    21 
    20 
    22 my $report;
    21 my $report;
    23 my $xref_file;
    22 my $xref_file;
    24 my $destfile;
    23 my $destfile;
    25 my $missing_destfile;
    24 my $missing_destfile;
       
    25 my $pkg_destfile;
    26 my @lines;
    26 my @lines;
    27 my $line;
    27 my $line;
    28 my $n;
    28 my $n;
    29 my $m;
    29 my $m;
    30 my $counter;
    30 my $counter;
    31 my $short_name;
    31 my $short_name;
    32 my $del_ok_issues = 1; # This variable determines whether to delete OK issues first.
    32 my $del_ok_issues = 1; # This variable determines whether to delete OK issues first.
    33 my $gen_missing_report = 1; # This variable determines whether to produce report for missing libraries.
    33 my $gen_missing_report = 1; # This variable determines whether to produce report for missing libraries.
    34 my $issues_num;
    34 my $issues_num;
    35 my $issue_name;
    35 my $issue_name;
    36 my $xref_name;
    36 my ($xref_name, $xref_type, $xref_line, $xref_hdr, $xref_def);
    37 my $xref_type;
       
    38 my $xref_line;
       
    39 my $xref_hdr;
       
    40 my $xref_def;
       
    41 my $delete_node;
    37 my $delete_node;
    42 my @non_public_list;
    38 my @non_public_list;
    43 my $current_item;
    39 my $current_item;
    44 my $check_against_xref;
    40 my $check_against_xref;
    45 my $temp_lib_num;
    41 my $temp_lib_num;
    46 my $temp_counter;
    42 my $temp_counter;
    47 
    43 my $sub_reports = 1; # This variable determines whether to generate sub-reports per package.
    48 if ($ARGV[1]) {
    44 my @lines_to_ignore = ("\\\\build\\\\", "\\\\compsupp\\\\", "\\\\uc_dll."); # This is the list of key words based on which a line potentially containing a package name will be ignored (skipped).
    49 	$report = $ARGV[0];
    45 my @pkgs;
    50 	$xref_file = $ARGV[1];
    46 my $baselinedlldir;
    51 	$destfile = "filtered_" . $report;
    47 my $lib_name;
    52 	$missing_destfile = "missing_" . $report;
    48 my $map_name;
    53 } else { 
    49 my $map_found;
    54 	die "Missing parameter(s). For example: la_filter.pl libraries_report.xml my_xref_file.txt"; 
    50 my ($layer_name, $package_name);
    55 }
    51 my $pkg_found;
       
    52 my $pkgs_num;
       
    53 my $add_pkg;
       
    54 my $nomap;
       
    55 my $help;
       
    56 
       
    57 sub usage($);
       
    58 sub help();
       
    59 sub usage_error();
       
    60 
       
    61 my %optmap = (  'libraries-report' => \$report,
       
    62 			    'xref-file' => \$xref_file,
       
    63 			    'baseline-dll-dir' => \$baselinedlldir,
       
    64 				'help' => \$help);
       
    65 
       
    66 GetOptions(\%optmap,
       
    67           'libraries-report=s',
       
    68           'xref-file=s',
       
    69           'baseline-dll-dir=s',
       
    70 		  'help!') 
       
    71           or usage_error();
       
    72 
       
    73 if ($help) {
       
    74 	help();
       
    75 }
       
    76 
       
    77 # --libraries-report is mandatory.
       
    78 usage_error(), unless (defined($report));
       
    79 
       
    80 # --xref-file is mandatory.
       
    81 usage_error(), unless (defined($xref_file));
       
    82 
       
    83 # Define output files based on the libraries report name.
       
    84 $destfile = "filtered_" . $report;
       
    85 $missing_destfile = "missing_" . $report;
    56 
    86 
    57 # Parse the input XMLs into hashrefs.
    87 # Parse the input XMLs into hashrefs.
    58 print "Parsing " . $report . "... ";
    88 print "Parsing " . $report . "... ";
    59 my $current_report = XMLin("./$report", keeproot => 1,
    89 my $current_report = XMLin("./$report", keeproot => 1,
    60     forcearray => [ 'header', 'baselineversion', 'currentversion', 'timestamp', 'day', 'month', 'year', 'hour', 'minute', 'second', #
    90     forcearray => [ 'header', 'baselineversion', 'currentversion', 'timestamp', 'day', 'month', 'year', 'hour', 'minute', 'second', #
   195 
   225 
   196 # Write new XML to dest file.
   226 # Write new XML to dest file.
   197 open OUT,">$destfile" or die("Cannot open file \"$destfile\" for writing. $!\n");
   227 open OUT,">$destfile" or die("Cannot open file \"$destfile\" for writing. $!\n");
   198 print OUT XMLout($current_report, keeproot => 1);
   228 print OUT XMLout($current_report, keeproot => 1);
   199 close OUT;
   229 close OUT;
       
   230 
       
   231 # Free up memory resources.
       
   232 $current_report = ();
   200 
   233 
   201 # Insert:	<?xml version="1.0" encoding="ASCII" standalone="no" ?>
   234 # Insert:	<?xml version="1.0" encoding="ASCII" standalone="no" ?>
   202 #			<?xml-stylesheet type="text/xsl" href="BBCResults.xsl"?>
   235 #			<?xml-stylesheet type="text/xsl" href="BBCResults.xsl"?>
   203 tie @lines, 'Tie::File', $destfile or die ("Cannot tie file \"$destfile\". $!\n");
   236 tie @lines, 'Tie::File', $destfile or die ("Cannot tie file \"$destfile\". $!\n");
   204 unshift @lines, "<?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?>";
   237 unshift @lines, "<?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?>";
   254 	tie @lines, 'Tie::File', $missing_destfile or die ("Cannot tie file \"$missing_destfile\". $!\n");
   287 	tie @lines, 'Tie::File', $missing_destfile or die ("Cannot tie file \"$missing_destfile\". $!\n");
   255 	unshift @lines, "<?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?>";
   288 	unshift @lines, "<?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?>";
   256 	unshift @lines, "<?xml version=\"1.0\" encoding=\"ASCII\" standalone=\"no\" ?>";
   289 	unshift @lines, "<?xml version=\"1.0\" encoding=\"ASCII\" standalone=\"no\" ?>";
   257 	untie @lines;
   290 	untie @lines;
   258 }
   291 }
       
   292 
       
   293 if (($sub_reports) && ($gen_missing_report)) { # Generate sub-reports per package.
       
   294 	# Parse the input XMLs into hashrefs again.
       
   295 	print "Parsing " . $missing_destfile . "... ";
       
   296 	my $current_report = XMLin("./$missing_destfile", keeproot => 1,
       
   297 		forcearray => [ 'header', 'baselineversion', 'currentversion', 'timestamp', 'day', 'month', 'year', 'hour', 'minute', 'second', #
       
   298 		'laversion', 'formatversion', 'cmdlineparms', 'parm', 'pname', 'pvalue', 'knownissuesversion', 'os', 'version', 'buildweek', 'issuelist',#
       
   299 		'library', 'name', 'comparefilename', 'shortname', 'baseplatform', 'currentplatform', 'issue', 'typeinfo', 'typeid', 'funcname', 'newfuncname', 'newfuncpos', #
       
   300 		'bc_severity', 'sc_severity', 'status', 'funcpos' ], keyattr => [] );
       
   301 	print "complete \n";
       
   302 	$lib_num = @{$current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}};
       
   303 	if (!defined($baselinedlldir)) { # Define baselinedlldir.
       
   304 		$n = 0;
       
   305 		foreach (@{$current_report->{'bbcresults'}->{'header'}->[0]->{'cmdlineparms'}->[0]->{'parm'}}) { # Find baselinedlldir.
       
   306 			if ($current_report->{'bbcresults'}->{'header'}->[0]->{'cmdlineparms'}->[0]->{'parm'}->[$n]->{'pname'}->[0] eq "baselinedlldir") {
       
   307 				$baselinedlldir = $current_report->{'bbcresults'}->{'header'}->[0]->{'cmdlineparms'}->[0]->{'parm'}->[$n]->{'pvalue'}->[0];
       
   308 				last;
       
   309 			}
       
   310 			$n++;
       
   311 		}
       
   312 	}
       
   313 	print "baselinedlldir: $baselinedlldir\n";
       
   314 	# Create the list of packages that link to missing libraries and generate sub-report for no-map file libraries.
       
   315 	$nomap = 0;
       
   316 	$n = 0;
       
   317 	while ($n < $lib_num) {
       
   318 		$lib_name = $current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}->[$n]->{'shortname'}->[0];
       
   319 		$map_name = $baselinedlldir . "\\" . $lib_name . ".map";
       
   320 		$map_found = 1;
       
   321 		# Find and open corresponding map file (.map or .dll.map).
       
   322 		open (FILE, "<$map_name") or $map_name = $baselinedlldir . "\\" . $lib_name . ".dll.map" and open (FILE, "<$map_name") or print "No map file found for $lib_name\n" and $map_found = 0;
       
   323 		if ($map_found) { 
       
   324 #			print "Found: $map_name for $lib_name\n";
       
   325 			$pkg_found = 0;
       
   326 			while ($line = <FILE>)
       
   327 			{
       
   328 				chomp $line;
       
   329 				# Get rid of spaces at the beginning.
       
   330 				$line =~ s/^\s+//;
       
   331 				if ($line =~ m/\\sf\\/) {
       
   332 					$pkg_found = 1; # Package potentially found.
       
   333 					# Check against lines_to_ignore.
       
   334 					foreach $current_item (@lines_to_ignore) {
       
   335 						if ($line =~ m/($current_item)/) { # Skip the line.
       
   336 							$pkg_found = 0; # Change it back to not found.
       
   337 							last;
       
   338 						}
       
   339 					}
       
   340 				}
       
   341 				if ($pkg_found) {
       
   342 					# Get rid of \sf\ and the part it follows.
       
   343 					$line =~ s/^.*\\sf\\//;
       
   344 					# Get only the package name (in between \ and \).
       
   345 					($layer_name, $package_name) = split /\\/,$line;
       
   346 					print "Package: $package_name found for: $lib_name (based on $map_name)\n";
       
   347 					$pkgs_num = @pkgs;
       
   348 					if ($pkgs_num == 0) { # Add the first package name by default.
       
   349 						push @pkgs, $package_name;
       
   350 					} else {
       
   351 						$add_pkg = 1;
       
   352 						$m = 0;
       
   353 						while ($m < $pkgs_num) {
       
   354 							if ($package_name eq @pkgs[$m]) { # Do not add a new package name.
       
   355 								$add_pkg = 0;
       
   356 							}
       
   357 							$m++;
       
   358 						}
       
   359 						if ($add_pkg) { # Add the new package name.
       
   360 							push @pkgs, $package_name;
       
   361 						}
       
   362 					}
       
   363 					last;
       
   364 				}
       
   365 			}
       
   366 			close FILE;
       
   367 			# Delete the node (to generate sub-report for libraries with no map file.
       
   368 			splice(@{$current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}},$n, 1);
       
   369 			$lib_num--;					
       
   370 		} else {
       
   371 			$nomap++;
       
   372 			$n++;
       
   373 		}
       
   374 	}
       
   375 	print "Number of libraries with no map file (most likely not a part of Public API): " . $nomap . "\n";
       
   376 	if ($nomap > 0) { # Save sub-report for no-map file libraries.
       
   377 		# Write new XML to dest file.
       
   378 		$pkg_destfile = "missing_with_no_map_file_" . $report;
       
   379 		open OUT,">$pkg_destfile" or die("Cannot open file \"$pkg_destfile\" for writing. $!\n");
       
   380 		print OUT XMLout($current_report, keeproot => 1);
       
   381 		close OUT;
       
   382 		# Insert:	<?xml version="1.0" encoding="ASCII" standalone="no" ?>
       
   383 		#			<?xml-stylesheet type="text/xsl" href="BBCResults.xsl"?>
       
   384 		tie @lines, 'Tie::File', $pkg_destfile or die ("Cannot tie file \"$pkg_destfile\". $!\n");
       
   385 		unshift @lines, "<?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?>";
       
   386 		unshift @lines, "<?xml version=\"1.0\" encoding=\"ASCII\" standalone=\"no\" ?>";
       
   387 		untie @lines;
       
   388 	}
       
   389 	print "Number of packages: " . @pkgs . "\n";
       
   390 	# Generate sub reports for all packages.
       
   391 	foreach $current_item (@pkgs) {
       
   392 	# Parse the input XMLs into hashrefs again.
       
   393 		print "Parsing " . $missing_destfile . "... ";
       
   394 		my $current_report = XMLin("./$missing_destfile", keeproot => 1,
       
   395 			forcearray => [ 'header', 'baselineversion', 'currentversion', 'timestamp', 'day', 'month', 'year', 'hour', 'minute', 'second', #
       
   396 			'laversion', 'formatversion', 'cmdlineparms', 'parm', 'pname', 'pvalue', 'knownissuesversion', 'os', 'version', 'buildweek', 'issuelist',#
       
   397 			'library', 'name', 'comparefilename', 'shortname', 'baseplatform', 'currentplatform', 'issue', 'typeinfo', 'typeid', 'funcname', 'newfuncname', 'newfuncpos', #
       
   398 			'bc_severity', 'sc_severity', 'status', 'funcpos' ], keyattr => [] );
       
   399 		print "complete \n";
       
   400 		$lib_num = @{$current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}};
       
   401 		$n = 0;
       
   402 		print "Processing libraries for $current_item... ";
       
   403 		while ($n < $lib_num) {
       
   404 			$lib_name = $current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}->[$n]->{'shortname'}->[0];
       
   405 			$map_name = $baselinedlldir . "\\" . $lib_name . ".map";
       
   406 			$map_found = 1;
       
   407 			# Find and open corresponding map file (.map or .dll.map).
       
   408 			open (FILE, "<$map_name") or $map_name = $baselinedlldir . "\\" . $lib_name . ".dll.map" and open (FILE, "<$map_name") or $map_found = 0;
       
   409 			if ($map_found) { 
       
   410 				$pkg_found = 0;
       
   411 				while ($line = <FILE>)
       
   412 				{
       
   413 					chomp $line;
       
   414 					# Get rid of spaces at the beginning.
       
   415 					$line =~ s/^\s+//;
       
   416 					if ($line =~ m/\\sf\\/) {
       
   417 						$pkg_found = 1; # Package potentially found.
       
   418 						# Check against lines_to_ignore.
       
   419 						foreach $current_item (@lines_to_ignore) {
       
   420 							if ($line =~ m/($current_item)/) { # Skip the line.
       
   421 								$pkg_found = 0; # Change it back to not found.
       
   422 								last;
       
   423 							}
       
   424 						}
       
   425 					}
       
   426 					if ($pkg_found) {
       
   427 						# Get rid of \sf\ and the part it follows.
       
   428 						$line =~ s/^.*\\sf\\//;
       
   429 						# Get only the package name (in between \ and \).
       
   430 						($layer_name, $package_name) = split /\\/,$line;
       
   431 						last;
       
   432 					}
       
   433 				}
       
   434 				close FILE;
       
   435 				if ($package_name ne $current_item) { # Remove the node from the report for the current package.
       
   436 					splice(@{$current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}},$n, 1);
       
   437 					$lib_num--;					
       
   438 				} else {
       
   439 					$n++;
       
   440 				}
       
   441 			} else { # Delete the node (library with no-map file).
       
   442 				splice(@{$current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}},$n, 1);
       
   443 				$lib_num--;					
       
   444 			}
       
   445 		}
       
   446 		# Write new XML to dest file.
       
   447 		$pkg_destfile = $current_item . "_" . $missing_destfile;
       
   448 		open OUT,">$pkg_destfile" or die("Cannot open file \"$pkg_destfile\" for writing. $!\n");
       
   449 		print OUT XMLout($current_report, keeproot => 1);
       
   450 		close OUT;
       
   451 		# Insert:	<?xml version="1.0" encoding="ASCII" standalone="no" ?>
       
   452 		#			<?xml-stylesheet type="text/xsl" href="BBCResults.xsl"?>
       
   453 		tie @lines, 'Tie::File', $pkg_destfile or die ("Cannot tie file \"$pkg_destfile\". $!\n");
       
   454 		unshift @lines, "<?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?>";
       
   455 		unshift @lines, "<?xml version=\"1.0\" encoding=\"ASCII\" standalone=\"no\" ?>";
       
   456 		untie @lines;
       
   457 		print "complete \n";
       
   458 		$lib_num = @{$current_report->{'bbcresults'}->{'issuelist'}->[0]->{'library'}};
       
   459 		print "Number of missing libraries in $current_item package: $lib_num\n";
       
   460 	}
       
   461 }
       
   462 
       
   463 exit 0;
       
   464 
       
   465 sub usage($)
       
   466 {
       
   467     my $error = shift;
       
   468     my $fh = $error == 0 ? *STDOUT : *STDERR;
       
   469     print $fh "la_filter.pl\n" .
       
   470             "Specify the libraries report and xref file\n" .
       
   471             "synopsis:\n" .
       
   472             "  la_filter.pl --help\n" .
       
   473             "  la_filter.pl [--libraries-report=XML_FILE] [--xref-file=TXT_FILE] [--baseline-dll-dir=PATH] \n" .
       
   474             "options:\n" .
       
   475             "  --help                        Display this help and exit.\n" .
       
   476             "  --libraries-report=XML_FILE   XML_FILE is the name of the libraries report xml file.\n" .
       
   477             "  --xref-file=TXT_FILE          TXT_FILE is the file containing the index of source code definitions generated by Ctags.\n" .
       
   478             "  --baseline-dll-dir=PATH       PATH is the full path to the directory containing map files (e.g. \\epoc32\\release\\armv5\\urel).\n" .
       
   479 			"                                If not specified then the baselinedlldir param from the libraries report will be used.\n";
       
   480     exit $error;            
       
   481 }
       
   482 
       
   483 sub help()
       
   484 {
       
   485     usage(0);
       
   486 }
       
   487 
       
   488 sub usage_error()
       
   489 {
       
   490     usage(1);
       
   491 }