summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2018-07-10 10:40:25 +0200
committerLubomir Rintel <lkundrak@v3.sk>2018-07-10 12:41:37 +0200
commit0f3f56695a87202b014f1a921c93c23a6d10ac62 (patch)
tree9ea9d26e087d2ee20923c9896e7a40ebf24e95b7
parent73fa1b54ef98d70402ea91e88fd15298eb151fb7 (diff)
downloadNetworkManager-0f3f56695a87202b014f1a921c93c23a6d10ac62.tar.gz
contrib: add checkpatch.pl
A naive code compliance checker. Invoke directly: contrib/scripts/checkpatch.pl 0001-switch-comments-to-klingon.patch contrib/scripts/checkpatch.pl hello.[ch] world.c Use from a commit hook: echo 'git format-patch --stdout -1 |contrib/scripts/checkpatch.pl || :>' \ >.git/hooks/post-commit Or view the documentation with "perldoc contrib/scripts/checkpatch.pl"
-rwxr-xr-xcontrib/scripts/checkpatch.pl224
1 files changed, 224 insertions, 0 deletions
diff --git a/contrib/scripts/checkpatch.pl b/contrib/scripts/checkpatch.pl
new file mode 100755
index 0000000000..f32fe2793c
--- /dev/null
+++ b/contrib/scripts/checkpatch.pl
@@ -0,0 +1,224 @@
+#!/usr/bin/perl -n
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright 2018 Red Hat, Inc.
+
+# $ perldoc checkpatch.pl for eye-pleasing view of the manual:
+
+=head1 NAME
+
+checkpatch.pl - emulate a serial modem
+
+=head1 SYNOPSIS
+
+checkpatch.pl [<file> ...]
+
+=head1 DESCRIPTION
+
+B<checkpatch.pl> checks source files or patches for common mistakes.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<< <file> >>
+
+A C source file or an unified diff.
+
+=back
+
+=cut
+
+use strict;
+use warnings;
+
+chomp;
+
+our $is_patch;
+our $is_file;
+
+our $seen_error;
+our $line; # Current line
+our $check_line; # Complain if errors are found on this line
+
+our @functions_seen;
+our $type;
+our $filename;
+
+sub new_hunk
+{
+ $type = undef;
+}
+
+sub new_file
+{
+ $filename = shift;
+ @functions_seen = ();
+}
+
+sub complain
+{
+ my $message = shift;
+
+ return unless $check_line;
+ warn "$ARGV:$.: $message:\n";
+ warn "> $line\n\n";
+ $seen_error = 1;
+}
+
+if ($is_patch) {
+ # This is a line of an unified diff
+ /^@@/ and new_hunk;
+ if (/^\+\+\+ (.*)/) {
+ new_file ($1);
+ next;
+ }
+ /^([ \+])(.*)/ or next;
+ $check_line = $1 eq '+';
+ $line = $2;
+} elsif ($is_file) {
+ # This is a line from full C file
+ $check_line = 1;
+ $line = $_;
+} else {
+ # We don't handle these yet
+ /^diff --cc/ and exit 0;
+ # We don't know if we're dealing with a patch or a C file yet
+ /^#/ and $is_file = 1;
+ /^---/ and $is_patch = 1;
+ $filename = '';
+ next;
+}
+
+if ($is_file and $filename ne $ARGV) {
+ new_file ($ARGV);
+ new_hunk;
+}
+
+next unless $filename =~ /\.[ch]$/;
+
+complain ('Tab following a space') if $line =~ / \t/;
+complain ('Trailing whitespace') if $line =~ /[ \t]$/;
+
+# Further on we process stuff without comments.
+$_ = $line;
+s/\s*\/\*.*\*\///;
+s/\s*\/\*.*//;
+s/\s*\/\/.*//;
+/^\s* \* / and next;
+new_hunk if $_ eq '';
+
+if (/^typedef*/) {
+ # We expect the { on the same line as the typedef. Otherwise it
+ # looks too much like a function declaration
+ complain ('Unexpected line break following a typedef') unless /[;{,]$/;
+ next;
+} elsif (/^[A-Za-z_][A-Za-z0-9_ ]*\*?$/ and /[a-z]/) {
+ # A function type
+ $type = $_;
+ #print "TYPE: >>> $line <<<\n";
+ next;
+} elsif ($type and /^([A-Za-z_][A-Za-z0-9_]*)(\s*)\(/) {
+ my @order = qw/^get_property$ ^set_property$ (?<!_iface|_class)_init$ ^constructor$ ^constructed
+ _new$ ^dispose$ ^finalize$ _class_init/;
+ my @following = ();
+ my @tmp = ();
+
+ # A function name
+ my $name = $1;
+ complain ('A single space should follow the function name') unless $2 eq ' ';
+
+ # Determine which function must not be preceding this one
+ foreach my $func (reverse @order) {
+ if ($name =~ /$func/) {
+ @following = @tmp;
+ #warn "$name ($func): ".join (' ', @following);
+ last;
+ }
+ push @tmp, $func;
+ }
+
+ # Check if an out-of-order function was seen
+ foreach my $func (@following) {
+ my @wrong = grep { /$func/ } @functions_seen;
+ complain (join (', ', map { "'$_'" } @wrong)." should follow '$name'") if @wrong;
+ }
+
+ push @functions_seen, $1;
+ $type = undef;
+ next;
+}
+
+if ($type) {
+ # We've seen what looked like a type in a function declaration,
+ # but the function declaration didn't follow.
+ if ($type =~ /^(struct|union)/ and $line eq '{') {
+ complain ("Brace should be one the same line as the '$type' declaration");
+ } else {
+ complain ("Expected a function declaration following '$type', but found something else");
+ }
+ $type = undef;
+}
+
+END {
+ if ($seen_error) {
+ warn "The patch does not validate.\n" if $is_patch;
+ warn "The file does not validate.\n" if $is_file;
+ $? = 1
+ }
+};
+
+=head1 EXAMPLES
+
+=over
+
+=item B<checkpatch.pl hello.c>
+
+Check a single file.
+
+=item B<git diff --cached |checkpatch.pl>
+
+Check the currently staged changes.
+
+=item B<git format-patch --stdout -1 |contrib/scripts/checkpatch.pl || :>
+
+A F<.git/hooks/post-commit> oneliner that, wisely, tolerates failures while
+still providing advice.
+
+=back
+
+=head1 BUGS
+
+Proabably too many.
+
+=head1 SEE ALSO
+
+F<CONTRIBUTING>
+
+=head1 COPYRIGHT
+
+Copyright 2018 Red Hat
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+=head1 AUTHOR
+
+Lubomir Rintel C<lkundrak@v3.sk>
+
+=cut