1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#!/usr/bin/perl
my $file=$ARGV[0];
my $max_column = 79;
my $indent = 2;
sub checkwarn {
my ($num, $col, $file, $line, $msg, $error) = @_;
my $w=$error?"error":"warning";
$col++;
print "$file:$num:$col: $w: $msg\n";
print " $line\n";
if($col < 80) {
my $pref = (' ' x $col);
print "${pref}^\n";
}
}
if(!$file) {
print "checksrc.pl <single C or H file>\n";
exit;
}
my $line = 1;
open(R, "<$file") || die;
my $copyright=0;
while(<R>) {
chomp;
my $l = $_;
my $column = 0;
# check for a copyright statement
if(!$copyright && ($l =~ /copyright .* \d\d\d\d/i)) {
$copyright=1;
}
# detect long lines
if(length($l) > $max_column) {
checkwarn($line, length($l), $file, $l, "Longer than $max_column columns");
}
# detect TAB characters
if($l =~ /^(.*)\t/) {
checkwarn($line, length($1), $file, $l, "Contains TAB character", 1);
}
# detect trailing white space
if($l =~ /^(\S+)[ \t]+\z/) {
checkwarn($line, length($1), $file, $l, "Trailing whitespace");
}
# detect return statements with parenthesis
# doesn't really work unless we filter off typecasts
#if($l =~ /(.*)return \(/) {
# checkwarn($line, length($1)+6, $file, $l, "return with paretheses");
#}
# check spaces after for/if/while
if($l =~ /^(.*)(for|if|while) \(/) {
if($1 =~ / *\#/) {
# this is a #if, treat it differently
}
else {
checkwarn($line, length($1)+length($2), $file, $l,
"$2 with space");
}
}
# check for "} else"
if($l =~ /^(.*)\} else/) {
checkwarn($line, length($1), $file, $l, "else after closing brace on same line");
}
# check for open brace first on line but not first column
# only alert if previous line ended with a close paren and wasn't a cpp
# line
if((($prevl =~ /\)\z/) && ($prevl !~ /^ *#/)) && ($l =~ /^( +)\{/)) {
checkwarn($line, length($1), $file, $l, "badly placed open brace");
}
# if the previous line starts with if/while/for AND ends with an open
# brace, check that this line is indented $indent more steps, if not
# a cpp line
if($prevl =~ /^( *)(if|while|for)\(.*\{\z/) {
my $first = length($1);
# this line has some character besides spaces
if(($l !~ /^ *#/) && ($l =~ /^( *)[^ ]/)) {
my $second = length($1);
my $expect = $first+$indent;
if($expect != $second) {
my $diff = $second - $first;
checkwarn($line, length($1), $file, $l,
"not indented $indent steps, uses $diff)");
}
}
}
# check for // letters, but skip them if a double quote or asterisk was
# on the same line to avoid strings and comments. Not reliable.
#if($l =~ /^([^\"*]*)\/\//) {
# checkwarn($line, length($1), $file, $l, "non-C89 compliant comment",
# 1);
#}
$line++;
$prevl = $l;
}
if(!$copyright) {
checkwarn(1, 0, $file, "", "Missing copyright statement", 1);
}
close(R);
|