ChibiOS/tools/style/stylecheck.pl

216 lines
5.7 KiB
Perl

#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
# Desired indentation.
my $indentation = 2;
if ($#ARGV != 0) {
print "\nUsage: stylecheck.pl source\n";
exit;
}
my $source = $ARGV[0];
open(my $in, "<", $source) or die "Can't open source: $!";
my $lineno = 0;
my @c_source = <$in>;
my $filename = $source;
$filename =~ y/\\/\//;
$filename = basename($filename);
my $cr = "\r";
my $lf = "\n";
my $tab = "\t";
my $c_comment = "";
my $state = "start";
sub style {
my $desc = shift;
print("style: $desc at line $lineno in \"$source\"\n");
}
sub error {
my $desc = shift;
print("error: $desc at line $lineno in \"$source\"\n");
}
my $emptycnt = 0;
foreach my $line (@c_source) {
$lineno += 1;
#****************************************************************************
# Check on EOL.
if (not ($line =~ /$cr$lf$/)) {
error "detected malformed EOL";
}
$line =~ s/$cr//;
$line =~ s/$lf//;
#****************************************************************************
# Check on trailing spaces.
if ($line =~ /\s$/) {
style "detected trailing spaces";
}
#****************************************************************************
# Check on TABs.
if ($line =~ /$tab/) {
style "detected TAB";
$line =~ s/$tab/ /;
}
#****************************************************************************
# Check on empty lines.
my $tmp = $line;
$tmp =~ s/\s//;
if (length($tmp) == 0) {
$emptycnt = $emptycnt + 1;
if ($emptycnt == 2) {
style "detected multiple empty lines"
}
next;
}
else {
$emptycnt = 0;
}
#****************************************************************************
# Stripping strings content for ease of parsing, all strings become _string_.
$line =~ s/\\\"//;
if ($line =~ s/(\"[^"]*\")/_string_/) {
# print "string: $1 replaced by _string_\n";
}
#******************************************************************************
# State machine handling.
if ($state eq "start") {
#******************************************************************************
# Comment start matching.
if ("$line" =~ /^\s*\/\*/) {
if ("$line" =~ /\*\//) {
# Special case of single line comments.
$line =~ /^\s*(\/\*.*\*\/)/;
}
else {
# Start of multi-line comment.
$line =~ /(\/\*.*)/;
$c_comment = $1 . " ";
$state = "incomment";
}
}
else {
#****************************************************************************
# Check on C++ comments.
if ($line =~ /\/\//) {
style "detected // comment";
}
#****************************************************************************
# Check on commas.
if ($line =~ /,\S/) {
style "detected comma not followed by space";
}
#****************************************************************************
# Check on loose semicolons.
if ($line =~ /\S\s;/) {
style "detected loose semicolon";
}
#****************************************************************************
# Check on glued keywords.
if ($line =~ /\sif\(/) {
style "detected glued \"if\"";
}
if ($line =~ /\sfor\(/) {
style "detected glued \"for\"";
}
if ($line =~ /\swhile\(/) {
style "detected glued \"while\"";
}
if ($line =~ /\)while/) {
style "detected glued \"while\"";
}
if ($line =~ /\sswitch\(/) {
style "detected glued \"switch\"";
}
if ($line =~ /\sdo\{/) {
style "detected glued \"do\"";
}
#****************************************************************************
# Check on loose parenthesis.
if ($line =~ /\(\s+/) {
style "detected loose \"(\"";
}
if ($line =~ /\S\s+\)/) {
style "detected loose \")\"";
}
#****************************************************************************
# Check on glued braces.
if ($line =~ /\)\{/) {
style "detected glued left brace";
}
if ($line =~ /\w\{/) {
style "detected glued left brace";
}
if ($line =~ /\}\w/) {
style "detected glued right brace";
}
#****************************************************************************
# Check on (some) operators.
if ($line =~ /\S!=/) {
style "detected glued != operator";
}
if ($line =~ /!=\S/) {
style "detected glued != operator";
}
if ($line =~ /\S==/) {
style "detected glued == operator";
}
if ($line =~ /!==S/) {
style "detected glued == operator";
}
#****************************************************************************
# Check function-call-like returns (not perfect so disabled).
if ($line =~ /return\s*\(/) {
if ($line =~ /return\s*\([\w\d\s\*]*\)\s*[^;]/) {
}
else {
# style "detected function-call-like return";
}
}
}
}
#******************************************************************************
# Scanning for comment end.
elsif ($state eq "incomment") {
if ("$line" =~ /\*\/\s*$/) {
# End of mult-line comment.
$line =~ /(.*\*\/)/;
$c_comment .= $1;
# print("$c_comment");
$state = "start";
}
else {
# Add the whole line.
$c_comment .= $line . " ";
# print("$c_comment");
}
}
}
close $in or die "$in: $!";