You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
8.5 KiB
Perl
292 lines
8.5 KiB
Perl
4 years ago
|
#!/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";
|
||
|
|
||
|
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;
|
||
|
my $c_comment_complete = 0;
|
||
|
my $c_comment = "";
|
||
|
my $state = "start";
|
||
|
foreach my $line (@c_source) {
|
||
|
|
||
|
$lineno += 1;
|
||
|
|
||
|
#****************************************************************************
|
||
|
# Processing comments after decoding.
|
||
|
if ($c_comment_complete != 0) {
|
||
|
# print($c_comment . "\n");
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Special case of lint comment.
|
||
|
if ("$c_comment" =~ /^\s*\/\*lint/) {
|
||
|
}
|
||
|
else {
|
||
|
#******************************************************************************
|
||
|
# Check on glued doxygen back-comment start.
|
||
|
if ("$c_comment" =~ /^\s*\/\*\*<[^\s]/) {
|
||
|
style "detected glued doxygen back-comment start";
|
||
|
}
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Check on glued doxygen comment start.
|
||
|
if ("$c_comment" =~ /^\s*\/\*\*[^\s<]/) {
|
||
|
style "detected glued doxygen comment start";
|
||
|
}
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Check on glued comment start.
|
||
|
if ("$c_comment" =~ /^\s*\/\*[^\s\*=]/) {
|
||
|
style "detected glued comment start";
|
||
|
}
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Check on lower case letter at comment beginning.
|
||
|
if ("$c_comment" =~ /^\s*\/\*\s*[a-z]/) {
|
||
|
style "detected lower case comment start";
|
||
|
}
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Check on loose comment stop.
|
||
|
# if ("$line" =~ /\s\*\//) {
|
||
|
# style "detected loose comment stop";
|
||
|
# }
|
||
|
}
|
||
|
|
||
|
$c_comment_complete = 0;
|
||
|
}
|
||
|
|
||
|
#****************************************************************************
|
||
|
# 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") {
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Standard separator.
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Comment start matching.
|
||
|
if ("$line" =~ /\/\*/) {
|
||
|
|
||
|
#******************************************************************************
|
||
|
# Single or multi line comments.
|
||
|
if ("$line" =~ /\*\//) {
|
||
|
# Special case of single line comments.
|
||
|
$line =~ /(\/\*.*\*\/)/;
|
||
|
$c_comment = $1;
|
||
|
$c_comment_complete = 1;
|
||
|
}
|
||
|
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.
|
||
|
# Before: <<= << >>= >> <= >= == != += -= *= /= %= &= |= ^=
|
||
|
if ($line =~ /(\(\S<<=?|\S>>=?|[^\s<]<=|[^\s>]>=|\S[=!+\-*\/%&|^]=)/) {
|
||
|
style "detected glued operator (1)";
|
||
|
}
|
||
|
# After: =
|
||
|
elsif ($line =~ /=[^\s=]/) {
|
||
|
style "detected glued assignment/comparison operator (2)";
|
||
|
}
|
||
|
# Before: =
|
||
|
elsif ($line =~ /[^\s\=\!\+\-\*\/\%\&\|\^\<\>]=/) {
|
||
|
style "detected glued assignment/comparison operator (3)";
|
||
|
}
|
||
|
# After: << >>
|
||
|
elsif ($line =~ /(<<|>>)[^\s=]/) {
|
||
|
style "detected glued assignment/comparison operator (4)";
|
||
|
}
|
||
|
# Before: && || ^^
|
||
|
elsif ($line =~ /\S(&&|\|\||\^\^)/) {
|
||
|
style "detected glued logical operator (1)";
|
||
|
}
|
||
|
# After: && || ^^
|
||
|
elsif ($line =~ /(&&|\|\||\^\^)\S/) {
|
||
|
style "detected glued logical operator (2)";
|
||
|
}
|
||
|
|
||
|
#****************************************************************************
|
||
|
# 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") {
|
||
|
# Left trimming.
|
||
|
$line =~ s/^\s+//;
|
||
|
if ("$line" =~ /^\s*\*\/\s*$/) {
|
||
|
# Just end of comment line.
|
||
|
$c_comment .= "*/";
|
||
|
$c_comment_complete = 1;
|
||
|
# print("$c_comment");
|
||
|
$state = "start";
|
||
|
}
|
||
|
elsif ("$line" =~ /\*\/\s*$/) {
|
||
|
# Text followed by end of comment.
|
||
|
$line =~ /(.*\*\/)/;
|
||
|
$c_comment .= " " . $1;
|
||
|
$c_comment_complete = 1;
|
||
|
# print("$c_comment");
|
||
|
$state = "start";
|
||
|
}
|
||
|
else {
|
||
|
# Add the whole line, remove first * and following spaces if any.
|
||
|
$line =~ s/^\*?\s*//;
|
||
|
$c_comment .= " " . $line;
|
||
|
# print("$c_comment");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
close $in or die "$in: $!";
|