mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-14 12:05:03 +00:00
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"
This commit is contained in:
parent
73fa1b54ef
commit
0f3f56695a
224
contrib/scripts/checkpatch.pl
Executable file
224
contrib/scripts/checkpatch.pl
Executable file
|
@ -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
|
Loading…
Reference in a new issue