summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@kernel.org>2022-04-14 14:25:01 +0200
committerPetri Latvala <petri.latvala@intel.com>2022-04-14 18:19:39 +0300
commit20d6ae043286b38bbfa2ae4b6f4199bb30f459b8 (patch)
treea27859968444829a2f8c4a8a014e85bfb7155e91 /scripts
parent697241a99a30774e3a43676f641f4cb601ecda18 (diff)
code_cov_parse_info: add support for exclude filters
It is interesting to have support not only for including, but also for excluding functions and files. Also, it is trivial to have support for it. When either one or both source/function filters are enabled, it will print at the console the regular expressions that are applied to functions and sources (if any), e. g.: $ cat << END >f1 +i915 gem - display -selftest END $ cat << END >f2 -/selftests END $ code_cov_parse_info dg1.info dg2.info --func-filters f1 --source-filters f2 --stat lines......: 72.1% (176 of 244 lines) functions..: 77.3% (17 of 22 functions) branches...: 50.0% (68 of 136 branches) Filters......: function regex (not match: m`display` m`selftest` and match: m`i915` m`gem`), source regex (match: m`/selftest`) and ignored source files where none of its code ran. Source files.: 0.99% (7 of 710 total), 77.78% (7 of 9 filtered) Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/code_cov_parse_info248
1 files changed, 177 insertions, 71 deletions
diff --git a/scripts/code_cov_parse_info b/scripts/code_cov_parse_info
index 0d9bac38..206145ef 100755
--- a/scripts/code_cov_parse_info
+++ b/scripts/code_cov_parse_info
@@ -17,21 +17,27 @@ my %used_source;
my %record;
my %files;
my @func_regexes;
+my @func_exclude_regexes;
my %test_names;
my @src_regexes;
+my @src_exclude_regexes;
my $verbose = 0;
my $ignore_unused = 0;
-my $only_i915 = 0;
-my $only_drm = 0;
my $skip_func = 0;
sub is_function_excluded($)
{
- return 0 if (!@func_regexes);
+ return 0 if (!@func_regexes && !@func_exclude_regexes);
my $func = shift;
+ foreach my $r (@func_exclude_regexes) {
+ return 1 if ($func =~ m/$r/);
+ }
+
+ return 0 if (!@func_regexes);
+
foreach my $r (@func_regexes) {
return 0 if ($func =~ m/$r/);
}
@@ -43,31 +49,14 @@ sub filter_file($)
{
my $s = shift;
- if ($only_drm) {
- # Please keep --only-drm doc updated with any changes her
- if ($s =~ m/\.h$/) {
- if ($s =~ m/trace/ || !($s =~ m/drm/)) {
- return 1;
- }
- }
- }
+ return 0 if (!@src_regexes && !@src_exclude_regexes);
- if ($only_i915) {
- # Please keep --only-i915 doc updated with any changes here
- if ($s =~ m/selftest/) {
- return 1;
- }
-
- # Please keep --only-i915 doc updated with any changes here
- if (!($s =~ m#drm/i915/# || $s =~ m#drm/ttm# || $s =~ m#drm/vgem#)) {
- return 1;
- }
+ foreach my $r (@src_exclude_regexes) {
+ return 1 if ($s =~ m/$r/);
}
return 0 if (!@src_regexes);
- my $func = shift;
-
foreach my $r (@src_regexes) {
return 0 if ($s =~ m/$r/);
}
@@ -468,6 +457,63 @@ sub print_summary()
}
}
+sub open_filter_file($$$)
+{
+ my $fname = shift;
+ my $include = shift;
+ my $exclude = shift;
+ my $match_str = "";
+ my $not_match_str = "";
+ my $filter = "";
+ my $i;
+
+ # Handle regexes that came from command line params
+
+ for ($i = 0;$i < scalar(@{$include}); $i++) {
+ my $op = @{$include}[$i];
+ $match_str .= sprintf "m`$op` ";
+ @{$include}[$i] = qr /$op/;
+ }
+
+ for ($i = 0;$i < scalar(@{$exclude}); $i++) {
+ my $op = @{$exclude}[$i];
+ $not_match_str .= sprintf "m`$op` ";
+ @{$exclude}[$i] = qr /$op/;
+ }
+
+ if ($fname) {
+ open IN, $fname or die "Can't open $fname";
+ while (<IN>) {
+ s/^\s+//;
+ s/\s+$//;
+ next if (m/^#/ || m/^$/);
+ if (m/^([+\-])\s*(.*)/) {
+ if ($1 eq "+") {
+ $match_str .= sprintf "m`$2` ";
+ push @{$include}, qr /$2/;
+ } else {
+ $not_match_str .= sprintf "m`$2` ";
+ push @{$exclude}, qr /$2/;
+ }
+ } else {
+ $match_str .= sprintf "m`$_` ";
+ push @{$include}, qr /$_/;
+ }
+ }
+ close IN;
+ }
+
+ $filter .= "not match: $not_match_str" if ($not_match_str);
+ if ($match_str) {
+ $filter .= "and " if ($filter ne "");
+ $filter .= "match: $match_str";
+ }
+
+ $filter =~ s/\s+$//;
+
+ return $filter;
+}
+
#
# Argument handling
#
@@ -482,6 +528,8 @@ my $func_filters;
my $src_filters;
my $show_files;
my $show_lines;
+my $only_i915;
+my $only_drm;
GetOptions(
"print-coverage|print_coverage|print|p" => \$print_used,
@@ -493,7 +541,11 @@ GetOptions(
"only-i915|only_i915" => \$only_i915,
"only-drm|only_drm" => \$only_drm,
"func-filters|f=s" => \$func_filters,
+ "include-func=s" => \@func_regexes,
+ "exclude-func=s" => \@func_exclude_regexes,
"source-filters|S=s" => \$src_filters,
+ "include-source=s" => \@src_regexes,
+ "exclude-source=s" => \@src_exclude_regexes,
"show-files|show_files" => \$show_files,
"show-lines|show_lines" => \$show_lines,
"help" => \$help,
@@ -513,64 +565,41 @@ pod2usage(1) if (!$print_used && !$filter && !$stat && !$print_unused);
my $filter_str = "";
my $has_filter;
-
-if ($func_filters) {
- open IN, $func_filters or die "Can't open $func_filters";
- while (<IN>) {
- s/^\s+//;
- s/\s+$//;
- next if (m/^#/ || m/^$/);
- push @func_regexes, qr /$_/;
- }
- close IN;
-}
-
-if ($src_filters) {
- open IN, $src_filters or die "Can't open $src_filters";
- while (<IN>) {
- s/^\s+//;
- s/\s+$//;
- next if (m/^#/ || m/^$/);
- push @src_regexes, qr /$_/;
- }
- close IN;
-}
-
-$ignore_unused = 1 if (@func_regexes);
+my $str;
if ($only_i915) {
- $filter_str = " non-i915 files";
- $has_filter = 1;
+ # Please keep in sync with the documentation
+ push @src_exclude_regexes, "selftest";
+ push @src_regexes, "drm/i915";
+ push @src_regexes, "drm/ttm";
+ push @src_regexes, "drm/vgem";
}
if ($only_drm) {
- $filter_str .= "," if ($filter_str ne "");
- $filter_str .= " non-drm headers";
- $has_filter = 1;
+ # Please keep in sync with the documentation
+ push @src_exclude_regexes, "trace.*\.h";
+ push @src_exclude_regexes, "drm.*\.h";
}
-if (@func_regexes) {
+$str = open_filter_file($func_filters, \@func_regexes, \@func_exclude_regexes);
+if ($str) {
$filter_str .= "," if ($filter_str ne "");
- $filter_str .= " unmatched functions";
- foreach my $r (@func_regexes) {
- $filter_str .= " m/$r/";
- }
-
+ $filter_str .= " function regex ($str)";
$has_filter = 1;
}
-if (@src_regexes) {
+$str = open_filter_file($src_filters, \@src_regexes, \@src_exclude_regexes);
+if ($str) {
$filter_str .= "," if ($filter_str ne "");
- $filter_str .= " unmatched source files";
- foreach my $r (@src_regexes) {
- $filter_str .= " m/$r/";
- }
+ $filter_str .= " source regex ($str)";
$has_filter = 1;
}
+$ignore_unused = 1 if (@func_regexes || @func_exclude_regexes);
+
if ($ignore_unused) {
$filter_str .= "," if ($filter_str ne "");
- $filter_str .= " source files where none of its code ran";
+ $filter_str .= " ignored source files where none of its code ran";
$has_filter = 1;
}
@@ -594,7 +623,7 @@ if ($has_filter) {
my $percent = 100. * $used_files / $all_files;
$filter_str =~ s/(.*),/$1 and/;
- printf "Ignored......:%s.\n", $filter_str;
+ printf "Filters......:%s.\n", $filter_str;
printf "Source files.: %.2f%% (%d of %d total)",
$percent, $used_files, $all_files;
@@ -699,16 +728,93 @@ Excluding files that match:
=item B<--func-filters> B<[filter's file]> or B<-f> B<[filter's file]>
-Take into account only the code coverage for the functions that match
-the regular expressions contained at the B<[filter's file]>.
+Use a file containing regular expressions (regex) to filter functions.
+
+Each line at B<[filter's file]> may contain a new regex:
+
+=over 4
+
+- Blank lines and lines starting with B<#> will be ignored;
+
+- Each line of the file will be handled as a new regex;
+
+- If B<+regex> is used, the filter will include B<regex> to the matches;
+
+- If B<-regex> is used, the filter will exclude B<regex> from the matches;
+
+- If the line doesn't start with neither B<+> nor B<->, containing just
+ B<regex>, the filter will include B<regex> to the matches.
+
+- Any whitespace/tab before or after B<regex> will be ignored.
+
+=back
+
+When both include and exclude regexes are found, exclude regexes are
+applied first and any functions that don't match the include regular
+expressions from the B<[filter's file]> will be ignored.
+
+Please notice that, when this filter is used, B<--ignore-unused> will be
+automaticaly enabled, as the final goal is to report per-function usage.
+
+=item B<--include-func> B<regex>
+
+Include B<regex> to the function filter. Can be used multiple times.
+
+When used together with B<--func-filters>, regexes here are handled first.
+
+Please notice that, when this filter is used, B<--ignore-unused> will be
+automaticaly enabled, as the final goal is to report per-function usage.
-When this filter is used, B<--ignore-unused> will be automaticaly enabled,
-as the final goal is to report per-function usage, and not per-file.
+=item B<--exclude-func> B<regex>
+
+Include B<regex> to the function filter. Can be used multiple times.
+
+When used together with B<--func-filters>, regexes here are handled first.
+
+Please notice that, when this filter is used, B<--ignore-unused> will be
+automaticaly enabled, as the final goal is to report per-function usage.
=item B<--source-filters> B<[filter's file]> or B<-S> B<[filter's file]>
-Takes into account only the code coverage for the source files that match
-the regular expressions contained at the B<[filter's file]>.
+Use a file containing regular expressions to filter source files.
+
+Each line of the file will be handled as a new regular expressions.
+Blank lines and lines starting with B<#> will be ignored.
+
+Each line at B<[filter's file]> may contain a new regex:
+
+=over 4
+
+- Blank lines and lines starting with B<#> will be ignored;
+
+- Each line of the file will be handled as a new regex;
+
+- If B<+regex> is used, the filter will include B<regex> to the matches;
+
+- If B<-regex> is used, the filter will exclude B<regex> from the matches;
+
+- If the line doesn't start with neither B<+> nor B<->, containing just
+ B<regex>, the filter will include B<regex> to the matches.
+
+- Any whitespace/tab before or after B<regex> will be ignored.
+
+=back
+
+When both include and exclude regexes are found, exclude regexes are
+applied first and any functions that don't match the include regular
+expressions from the B<[filter's file]> will be ignored.
+
+=item B<--include-src> B<regex>
+
+Include B<regex> to the sources filter. Can be used multiple times.
+
+When used together with B<--src-filters>, regexes here are handled first.
+
+=item B<--exclude-src> B<regex>
+
+Include B<regex> to the sources filter. Can be used multiple times.
+
+When used together with B<--src-filters>, regexes here are handled first.
=item B<--ignore-unused> or B<--ignore_unused>