Commits

Anonymous committed 974783e

lcov: add option to exclude external files

Implement an option for users to specify that external source files should
be excluded when capturing coverage data. External source files are files
which are not located in the directories specified by the --directory and
--base-directory options of lcov/geninfo.

Comments (0)

Files changed (7)

 sub debug($);
 sub int_handler();
 sub parse_ignore_errors(@);
+sub is_external($);
 
 
 # Global variables
 our $maxdepth;
 our $no_markers = 0;
 our $opt_derive_func_data = 0;
+our $opt_external = 1;
+our $opt_no_external;
 our $debug = 0;
 our $gcov_caps;
 our @gcov_options;
+our @internal_dirs;
 
 our $cwd = `pwd`;
 chomp($cwd);
 		"geninfo_adjust_testname"	=> \$adjust_testname,
 		"geninfo_checksum"		=> \$checksum,
 		"geninfo_no_checksum"		=> \$no_checksum, # deprecated
-		"geninfo_compat_libtool"	=> \$compat_libtool});
+		"geninfo_compat_libtool"	=> \$compat_libtool,
+		"geninfo_external"		=> \$opt_external,
+	});
 
 	# Merge options
 	if (defined($no_checksum))
 		"no-markers" => \$no_markers,
 		"derive-func-data" => \$opt_derive_func_data,
 		"debug" => \$debug,
+		"external" => \$opt_external,
+		"no-external" => \$opt_no_external,
 		))
 {
 	print(STDERR "Use $tool_name --help to get usage information\n");
 		$compat_libtool = ($no_compat_libtool ? 0 : 1);
 		$no_compat_libtool = undef;
 	}
+
+	if (defined($opt_no_external)) {
+		$opt_external = 0;
+		$opt_no_external = undef;
+	}
 }
 
 @data_directory = @ARGV;
 	}
 }
 
+# Build list of directories to identify external files
+foreach my $entry(@data_directory, $base_directory) {
+	next if (!defined($entry));
+	push(@internal_dirs, solve_relative_path($cwd, $entry));
+}
+
 # Do something
 foreach my $entry (@data_directory) {
 	gen_info($entry);
       --function-coverage           Capture function call counts
       --no-markers                  Ignore exclusion markers in source code
       --derive-func-data            Generate function data from line data
+      --(no-)external               Include (ignore) data for external files
 
 For more information see: $lcov_url
 END_OF_USAGE
 			}
 		}
 
+		# Skip external files if requested
+		if (!$opt_external) {
+			if (is_external($source_filename)) {
+				info("  ignoring data for external file ".
+				     "$source_filename\n");
+				unlink($gcov_file);
+				next;
+			}
+		}
+
 		# Write absolute path of source file
 		printf(INFO_HANDLE "SF:%s\n", $source_filename);
 
 
 	# Remove .
 	$result =~ s/\/\.\//\//g;
+	$result =~ s/\/\.$/\//g;
+
+	# Remove trailing /
+	$result =~ s/\/$//g;
 
 	# Solve ..
 	while ($result =~ s/\/[^\/]+\/\.\.\//\//)
 		$ignore[$item_id] = 1;
 	}
 }
+
+#
+# is_external(filename)
+#
+# Determine if a file is located outside of the specified data directories.
+#
+
+sub is_external($)
+{
+	my ($filename) = @_;
+	my $dir;
+
+	foreach $dir (@internal_dirs) {
+		return 0 if ($filename =~ /^\Q$dir\/\E/);
+	}
+	return 1;
+}
 our $opt_no_list_full_path;
 our $opt_list_width = 80;
 our $opt_list_truncate_max = 20;
+our $opt_external;
+our $opt_no_external;
 our $ln_overall_found;
 our $ln_overall_hit;
 our $fn_overall_found;
 		"debug" => \$opt_debug,
 		"list-full-path" => \$opt_list_full_path,
 		"no-list-full-path" => \$opt_no_list_full_path,
+		"external" => \$opt_external,
+		"no-external" => \$opt_no_external,
 		))
 {
 	print(STDERR "Use $tool_name --help to get usage information\n");
 		$opt_list_full_path = ($opt_no_list_full_path ? 0 : 1);
 		$opt_no_list_full_path = undef;
 	}
+
+	if (defined($opt_no_external)) {
+		$opt_external = 0;
+		$opt_no_external = undef;
+	}
 }
 
 # Check for help option
       --no-markers                Ignore exclusion markers in source code
       --derive-func-data          Generate function data from line data
       --list-full-path            Print full path during a list operation
+      --(no-)external             Include (ignore) data for external files
 
 For more information see: $lcov_url
 END_OF_USAGE
 	{
 		@param = (@param, "--debug");
 	}
+	if (defined($opt_external) && $opt_external)
+	{
+		@param = (@param, "--external");
+	}
+	if (defined($opt_external) && !$opt_external)
+	{
+		@param = (@param, "--no-external");
+	}
 	system(@param) and exit($? >> 8);
 }
 
 	@echo
 	$(LCOV) --zerocounters --directory .
 	./example
-	$(LCOV) --capture --directory . --output-file trace_noargs.info --test-name test_noargs
+	$(LCOV) --capture --directory . --output-file trace_noargs.info --test-name test_noargs --no-external
 
 test_2_to_2000:
 	@echo
 	@echo
 	$(LCOV) --zerocounters --directory .
 	./example 2 2000
-	$(LCOV) --capture --directory . --output-file trace_args.info --test-name test_2_to_2000
+	$(LCOV) --capture --directory . --output-file trace_args.info --test-name test_2_to_2000 --no-external
 
 test_overflow:
 	@echo
 	@echo
 	$(LCOV) --zerocounters --directory .
 	./example 0 100000 || true
-	$(LCOV) --capture --directory . --output-file trace_overflow.info --test-name "test_overflow"
+	$(LCOV) --capture --directory . --output-file trace_overflow.info --test-name "test_overflow" --no-external
 
 clean:
 	rm -rf *.o *.bb *.bbg *.da *.gcno *.gcda *.info output example \
 # choosing a directory prefix in list output. This value is ignored when
 # lcov_list_full_path is non-zero.
 lcov_list_truncate_max = 20
+
+# Specify whether to capture coverage data for external source files (can
+# be overridden by the --external and --no-external options of geninfo/lcov)
+geninfo_external = 1
 .br
 .RB [ \-\-no\-recursion ]
 .I directory
+.RB [ \-\-external ]
+.RB [ \-\-no\-external ]
 .RE
 .SH DESCRIPTION
 .B geninfo 
 libtool, disable this option to prevent problems when capturing coverage data.
 .RE
 
+.B \-\-external
+.br
+.B \-\-no\-external
+.br
+.RS
+Specify whether to capture coverage data for external source files.
+
+External source files are files which are not located in one of the directories
+specified by \-\-directory or \-\-base\-directory. Use \-\-external to include
+external source files while capturing coverage data or \-\-no\-external to
+ignore this data.
+
+Data for external source files is
+.B included
+by default.
+.RE
+
 .B \-f
 .br
 .B \-\-follow
 .RB [ \-q | \-\-quiet ]
 .br
 .RB [ \-\-no\-markers ]
+.RB [ \-\-external ]
+.RB [ \-\-no\-external ]
 .br
 .RE
 
 Note that you may specify this option more than once.
 .RE
 
+.B \-\-external
+.br
+.B \-\-no\-external
+.br
+.RS
+Specify whether to capture coverage data for external source files.
+
+External source files are files which are not located in one of the directories
+specified by \-\-directory or \-\-base\-directory. Use \-\-external to include
+external source files while capturing coverage data or \-\-no\-external to
+ignore this data.
+
+Data for external source files is
+.B included
+by default.
+.RE
+
 .B \-e
 .I tracefile
 .I pattern
 .br
 # This value is ignored when lcov_list_full_path is non\-zero.
 .br
+lcov_list_truncate_max = 20
 
-lcov_list_truncate_max = 20
+# Specify whether to capture coverage data for external source
+.br
+# files
+.br
+geninfo_external = 1
+.br
 .PP
 
 .SH OPTIONS
 Default is 1.
 .PP
 
+.BR geninfo_external " ="
+.IR 0 | 1
+.IP
+If non\-zero, capture coverage data for external source files.
+
+External source files are files which are not located in one of the directories
+specified by the \-\-directory or \-\-base\-directory options of
+.BR lcov / geninfo .
+
+Default is 1.
+.PP
+
+
 .BR lcov_gcov_dir " ="
 .I path_to_kernel_coverage_data
 .IP