Skip to content
Snippets Groups Projects
checksrc.pl 5.87 KiB
Newer Older
  • Learn to ignore specific revisions
  • #***************************************************************************
    #                                  _   _ ____  _
    #  Project                     ___| | | |  _ \| |
    #                             / __| | | | |_) | |
    #                            | (__| |_| |  _ <| |___
    #                             \___|\___/|_| \_\_____|
    #
    
    # Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
    
    #
    # This software is licensed as described in the file COPYING, which
    # you should have received as part of this distribution. The terms
    # are also available at http://curl.haxx.se/docs/copyright.html.
    #
    # You may opt to use, copy, modify, merge, publish, distribute and/or sell
    # copies of the Software, and permit persons to whom the Software is
    # furnished to do so, under the terms of the COPYING file.
    #
    # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
    # KIND, either express or implied.
    #
    ###########################################################################
    
    
    my $max_column = 79;
    my $indent = 2;
    
    
    my $warnings;
    my $errors;
    
    my $file;
    my $dir=".";
    
    sub checkwarn {
        my ($num, $col, $file, $line, $msg, $error) = @_;
    
        my $w=$error?"error":"warning";
    
    
        if($w) {
            $warnings++;
        }
        else {
            $errors++;
        }
    
    
        $col++;
        print "$file:$num:$col: $w: $msg\n";
        print " $line\n";
    
        if($col < 80) {
            my $pref = (' ' x $col);
            print "${pref}^\n";
        }
    }
    
    
    $file = shift @ARGV;
    
    
    while(1) {
    
        if($file =~ /-D(.*)/) {
            $dir = $1;
            $file = shift @ARGV;
            next;
        }
        elsif($file =~ /-W(.*)/) {
    
        print "checksrc.pl [option] <file1> [file2] ...\n";
        print " Options:\n";
        print "  -D[DIR]   Directory to prepend file names\n";
    
        print "  -W[file]  Whitelist the given file - ignore all its flaws\n";
    
    Yang Tse's avatar
    Yang Tse committed
        if("$wlist" !~ / $file /) {
    
            my $fullname = $file;
    
            $fullname = "$dir/$file" if ($fullname !~ '^\.?\.?/');
    
            scanfile($fullname);
    
        $file = shift @ARGV;
    
    } while($file);
    
    sub scanfile {
        my ($file) = @_;
    
        my $line = 1;
        my $prevl;
        my $l;
        open(R, "<$file") || die "failed to open $file";
    
        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 =~ /^(.*)[ \t]+\z/) {
    
                checkwarn($line, length($1), $file, $l, "Trailing whitespace");
            }
    
            # 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 spaces after open paren 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)+1, $file, $l,
                              "$2 with space first in condition");
                }
    
            # check for "return(" without space
            if($l =~ /^(.*)return\(/) {
                if($1 =~ / *\#/) {
                    # this is a #if, treat it differently
                }
                else {
                    checkwarn($line, length($1)+6, $file, $l,
                              "return without space before paren");
                }
            }
            
    
            # check for "} else"
    
            if($l =~ /^(.*)\} *else/) {
    
                checkwarn($line, length($1), $file, $l, "else after closing brace on same line");
            }
    
            # check for "){"
            if($l =~ /^(.*)\)\{/) {
                checkwarn($line, length($1)+1, $file, $l, "missing space after close paren");
            }
    
    
            # scan for use of banned functions
            if($l =~ /^(.*\W)(sprintf|vsprintf|strcat|strncat|gets)\s*\(/) {
                checkwarn($line, length($1), $file, $l,
                          "use of $2 is banned");
            }
    
    
            # 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)");
    
                    }
    
        if(!$copyright) {
            checkwarn(1, 0, $file, "", "Missing copyright statement", 1);
        }
    
    
    if($errors || $warnings) {
    
        printf "checksrc: %d errors and %d warnings\n", $errors, $warnings;
    
        exit 5; # return failure
    }