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