All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mauro.chehab@linux.intel.com>
To: igt-dev@lists.freedesktop.org,
	Petri Latvala <petri.latvala@intel.com>,
	Ch Sai Gowtham <sai.gowtham.ch@intel.com>,
	Andrzej Hajda <andrzej.hajda@intel.com>
Subject: [igt-dev] [PATCH v2 11/12] code_cov_parse_info: add support for exclude filters
Date: Tue, 12 Apr 2022 10:59:10 +0200	[thread overview]
Message-ID: <44750fbf7c569f1da80a8f443b07df963730e28f.1649753814.git.mchehab@kernel.org> (raw)
In-Reply-To: <cover.1649753814.git.mchehab@kernel.org>

From: Mauro Carvalho Chehab <mchehab@kernel.org>

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-filter 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)

Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
---

To avoid mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH v2 00/12] at: https://lore.kernel.org/all/cover.1649753814.git.mchehab@kernel.org/

 scripts/code_cov_parse_info | 172 +++++++++++++++++++++++++-----------
 1 file changed, 122 insertions(+), 50 deletions(-)

diff --git a/scripts/code_cov_parse_info b/scripts/code_cov_parse_info
index 0d9bac38cea9..7336f2be7978 100755
--- a/scripts/code_cov_parse_info
+++ b/scripts/code_cov_parse_info
@@ -17,8 +17,10 @@ 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;
@@ -28,10 +30,16 @@ my $skip_func = 0;
 
 sub is_function_excluded($)
 {
+	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);
 
-	my $func = shift;
-
 	foreach my $r (@func_regexes) {
 		return 0 if ($func =~ m/$r/);
 	}
@@ -64,10 +72,14 @@ sub filter_file($)
 		}
 	}
 
+	return 0 if (!@src_regexes && !@src_exclude_regexes);
+
+	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 +480,46 @@ 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 = "";
+
+	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
 #
@@ -515,62 +567,35 @@ 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;
+	my $str = open_filter_file($func_filters, \@func_regexes, \@func_exclude_regexes);
+	$filter_str .= "," if ($filter_str ne "");
+	$filter_str .= " function regex ($str)";
+	$has_filter = 1;
 }
 
 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;
+	my $str = open_filter_file($src_filters, \@src_regexes, \@src_exclude_regexes);
+	$filter_str .= "," if ($filter_str ne "");
+	$filter_str .= " source regex ($str)";
+	$has_filter = 1;
 }
 
-$ignore_unused = 1 if (@func_regexes);
+$ignore_unused = 1 if (@func_regexes || @func_exclude_regexes);
 
 if ($only_i915) {
-	$filter_str = " non-i915 files";
+	$filter_str = " ignored non-i915 files";
 	$has_filter = 1;
 }
 
 if ($only_drm) {
 	$filter_str .= "," if ($filter_str ne "");
-	$filter_str .= " non-drm headers";
-	$has_filter = 1;
-}
-
-if (@func_regexes) {
-	$filter_str .= "," if ($filter_str ne "");
-	$filter_str .= " unmatched functions";
-	foreach my $r (@func_regexes) {
-		$filter_str .= " m/$r/";
-	}
-
-	$has_filter = 1;
-}
-
-if (@src_regexes) {
-	$filter_str .= "," if ($filter_str ne "");
-	$filter_str .= " unmatched source files";
-	foreach my $r (@src_regexes) {
-		$filter_str .= " m/$r/";
-	}
+	$filter_str .= " ignored non-drm headers";
 	$has_filter = 1;
 }
 
 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 +619,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 +724,63 @@ 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.
 
-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.
+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<--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<--ignore-unused> or B<--ignore_unused>
 
-- 
2.35.1

  parent reply	other threads:[~2022-04-12  8:59 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-12  8:58 [igt-dev] [PATCH v2 00/12] code coverage: some improvements Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 01/12] scripts/code_cov*: remove the extensions from them Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 02/12] scripts/code_cov_parse_info: add a tool to parse code coverage info files Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 03/12] scripts/code_cov_gen_report: add support for filtering " Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 04/12] runner: execute code coverage script also from PATH Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 05/12] scripts/meson.build: install code coverage scripts Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 06/12] scripts/code_cov_selftest.sh: test if IGT code coverage is working Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 07/12] docs/code_coverage.md: document the code coverage filter script Mauro Carvalho Chehab
2022-04-13 13:14   ` Andrzej Hajda
2022-04-12  8:59 ` [igt-dev] [PATCH v2 08/12] scripts/code_cov_parse_info: better handle test name Mauro Carvalho Chehab
2022-04-13 13:15   ` Andrzej Hajda
2022-04-12  8:59 ` [igt-dev] [PATCH v2 09/12] code_cov_parse_info: fix error handling when opening files Mauro Carvalho Chehab
2022-04-13 13:27   ` Andrzej Hajda
2022-04-14  5:48     ` Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 10/12] code_cov_parse_info: fix --show-lines logic Mauro Carvalho Chehab
2022-04-12  8:59 ` Mauro Carvalho Chehab [this message]
2022-04-13 13:53   ` [igt-dev] [PATCH v2 11/12] code_cov_parse_info: add support for exclude filters Andrzej Hajda
2022-04-14  7:03     ` Mauro Carvalho Chehab
2022-04-12  8:59 ` [igt-dev] [PATCH v2 12/12] code_cov_parse_info: add support for generating html reports Mauro Carvalho Chehab
2022-04-13 13:59   ` Andrzej Hajda
2022-04-12  9:40 ` [igt-dev] ✗ GitLab.Pipeline: warning for code coverage: some improvements (rev2) Patchwork
2022-04-12 10:04 ` [igt-dev] ✗ Fi.CI.BAT: failure " Patchwork
2022-04-14  7:28 ` [igt-dev] ✗ Fi.CI.BUILD: failure for code coverage: some improvements (rev3) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44750fbf7c569f1da80a8f443b07df963730e28f.1649753814.git.mchehab@kernel.org \
    --to=mauro.chehab@linux.intel.com \
    --cc=andrzej.hajda@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=petri.latvala@intel.com \
    --cc=sai.gowtham.ch@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.