[PATCH 1/7] checkpatch: Implement new --ignore-cfg parameter

From: Knut Omang
Date: Thu Nov 16 2017 - 12:04:18 EST


This parameter is intended to be used in a subsequent commit to kbuild to allow
a convenient way to run checkpatch from make.

The parameter --ignore-cfg causes checkpatch.pl to look for the file given as
parameter, either directly from where checkpatch is executed, or in the
directory where the file to check is located. With this parameter checkpatch is
now limited to run on a single file for each invocation. This should not be a
problem for the Makefile scenario as it is the standard behaviour anyway.

This file accepts the following syntax:

# comments
line_len <n>
except checkpatch_type [files ...]
pervasive checkpatch_type1 [checkpatch_type2 ...]

The line_len command defines the upper bound of characters per line tolerated in
this directory.

The except command takes a checkpatch type such as for example MACRO_ARG_REUSE,
and a set of files that should not be subject to this particular check type.

The pervasive command disables the listed types of checks for all the files in
the directory. The except and pervasive command can be used cumulatively to add
more exceptions.

By accepting comments and multiple lines of commands, the idea is that the
maintainer or someone else with good knowledge of the code can maintain a file
per directory and group the different commands into commented sections that can
serve both as documentation of the current checkpatch status, a way to define
the line of tolerance (and gradually tighten it as fixes comes in) and as
documentation of TODOs and dont's if there are well justified exceptions.

Signed-off-by: Knut Omang <knut.omang@xxxxxxxxxx>
Acked-by: HÃkon Bugge <haakon.bugge@xxxxxxxxxx>
Acked-by: Ãsmund Ãstvold <asmund.ostvold@xxxxxxxxxx>
---
scripts/checkpatch.pl | 57 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 8b80bac..834a1d8 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -48,6 +48,7 @@ my %ignore_type = ();
my @ignore = ();
my $help = 0;
my $configuration_file = ".checkpatch.conf";
+my $ignore_cfg_file;
my $max_line_length = 80;
my $ignore_perl_version = 0;
my $minimum_perl_version = 5.10.0;
@@ -90,6 +91,9 @@ Options:
--list-types list the possible message types
--types TYPE(,TYPE2...) show only these comma separated message types
--ignore TYPE(,TYPE2...) ignore various comma separated message types
+ --ignore-cfg FILE parse this file for a detailed file specific ignore list,
+ silently exit without checking if an ignore config file
+ is not found.
--show-types show the specific message type in the output
--max-line-length=n set the maximum line length, if exceeded, warn
--min-conf-desc-length=n set the min description length, if shorter, warn
@@ -201,6 +205,7 @@ GetOptions(
'terse!' => \$terse,
'showfile!' => \$showfile,
'f|file!' => \$file,
+ 'ignore-cfg=s' => \$ignore_cfg_file,
'g|git!' => \$git,
'subjective!' => \$check,
'strict!' => \$check,
@@ -233,6 +238,9 @@ help(0) if ($help);

list_types(0) if ($list_types);

+# Enforce --strict if used with a ignore configuration file:
+$check = 1 if defined($ignore_cfg_file);
+
$fix = 1 if ($fix_inplace);
$check_orig = $check;

@@ -291,6 +299,7 @@ sub hash_show_words {
}
}

+parse_ignore_cfg_file(@ARGV) || exit(0);
hash_save_array_words(\%ignore_type, \@ignore);
hash_save_array_words(\%use_type, \@use);

@@ -2160,6 +2169,54 @@ sub pos_last_openparen {
return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
}

+# Checkpatch suppression list configuration file support
+#
+# See Documentation/dev-tools/run-checkpatch.rst
+#
+sub parse_ignore_cfg_file {
+ defined($ignore_cfg_file) || return 1;
+ my $path = shift(@_);
+ my $filename = basename($path);
+ my $dir = dirname($path);
+ my %IgnoreCfgKeywords = (
+ 'except' => sub { my $type = shift(@_);
+ grep( /^$filename$/, @_ ) && push(@ignore, $type);
+ },
+ 'pervasive' => sub { push(@ignore, @_); },
+ 'line_len' => sub { $max_line_length = shift(@_); }
+ );
+ my $ignfile;
+
+ ( -f $ignore_cfg_file ) || ( $ignore_cfg_file = "$dir/$ignore_cfg_file" );
+ ( ! -f $ignore_cfg_file ) && return 0;
+ open($ignfile, '<', "$ignore_cfg_file") || return 0;
+
+ ($#_ >= 0) &&
+ die "$P: The --ignore-cfg option is only supported with one source file at a time!\n";
+
+ while (<$ignfile>) {
+ my $line = $_;
+
+ $line =~ s/\s*\n?$//g;
+ $line =~ s/^\s*//g;
+ $line =~ s/\s+/ /g;
+ $line =~ s/#.*//g;
+ $line =~ m/^\s*$/ && next;
+
+ my @words = split(" ", $line);
+ my $kw = shift(@words);
+ defined($kw) or next;
+ my $cmd = $IgnoreCfgKeywords{$kw};
+ if ( !defined($cmd) ) {
+ print "$line\n";
+ warn("Unknown keyword \"$kw\" in file \"$ignore_cfg_file\"\n");
+ next;
+ }
+ &$cmd(@words);
+ }
+ return 1;
+}
+
sub process {
my $filename = shift;

--
git-series 0.9.1