Imported Upstream version 7.59.0
[platform/upstream/curl.git] / lib / checksrc.pl
index f31083a..c86222b 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
 #***************************************************************************
 #                                  _   _ ____  _
 #  Project                     ___| | | |  _ \| |
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 2011 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 2011 - 2018, 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
@@ -26,7 +26,7 @@ my $indent = 2;
 
 my $warnings;
 my $errors;
-my $supressed; # whitelisted problems
+my $suppressed; # whitelisted problems
 my $file;
 my $dir=".";
 my $wlist;
@@ -35,10 +35,10 @@ my $verbose;
 my %whitelist;
 
 my %warnings = (
-    'LONGLINE' =>         "Line longer than $max_column",
-    'TABS' =>             'TAB characters not allowed',
-    'TRAILINGSPACE' =>    'Trailing white space on the line',
-    'CPPCOMMENTS' =>      '// comment detected',
+    'LONGLINE'         => "Line longer than $max_column",
+    'TABS'             => 'TAB characters not allowed',
+    'TRAILINGSPACE'    => 'Trailing white space on the line',
+    'CPPCOMMENTS'      => '// comment detected',
     'SPACEBEFOREPAREN' => 'space before an open parenthesis',
     'SPACEAFTERPAREN'  => 'space after open parenthesis',
     'SPACEBEFORECLOSE' => 'space before a close parenthesis',
@@ -55,7 +55,14 @@ my %warnings = (
     'COPYRIGHT'        => 'file missing a copyright statement',
     'BADCOMMAND'       => 'bad !checksrc! instruction',
     'UNUSEDIGNORE'     => 'a warning ignore was not used',
-    'OPENCOMMENT'      => 'file ended with a /* comment still "open"'
+    'OPENCOMMENT'      => 'file ended with a /* comment still "open"',
+    'ASTERISKSPACE'    => 'pointer declared with space after asterisk',
+    'ASTERISKNOSPACE'  => 'pointer declared without space before asterisk',
+    'ASSIGNWITHINCONDITION' => 'assignment within conditional expression',
+    'EQUALSNOSPACE'    => 'equals sign without following space',
+    'NOSPACEEQUALS'    => 'equals sign without preceding space',
+    'SEMINOSPACE'      => 'semicolon without following space',
+    'MULTISPACE'       => 'multiple spaces used when not suitable',
     );
 
 sub readwhitelist {
@@ -94,7 +101,7 @@ sub checkwarn {
     }
 
     if($nowarn) {
-        $supressed++;
+        $suppressed++;
         if($w) {
             $swarnings++;
         }
@@ -135,6 +142,16 @@ while(1) {
         $file = shift @ARGV;
         next;
     }
+    elsif($file =~ /-i([1-9])/) {
+        $indent = $1 + 0;
+        $file = shift @ARGV;
+        next;
+    }
+    elsif($file =~ /-m([0-9]+)/) {
+        $max_column = $1 + 0;
+        $file = shift @ARGV;
+        next;
+    }
     elsif($file =~ /^(-h|--help)/) {
         undef $file;
         last;
@@ -149,6 +166,8 @@ if(!$file) {
     print "  -D[DIR]   Directory to prepend file names\n";
     print "  -h        Show help output\n";
     print "  -W[file]  Whitelist the given file - ignore all its flaws\n";
+    print "  -i<n>     Indent spaces. Default: 2\n";
+    print "  -m<n>     Maximum line length. Default: 79\n";
     print "\nDetects and warns for these problems:\n";
     for(sort keys %warnings) {
         printf (" %-18s: %s\n", $_, $warnings{$_});
@@ -241,6 +260,12 @@ sub checksrc {
     }
 }
 
+sub nostrings {
+    my ($str) = @_;
+    $str =~ s/\".*\"//g;
+    return $str;
+}
+
 sub scanfile {
     my ($file) = @_;
 
@@ -327,17 +352,38 @@ sub scanfile {
                       $line, length($1), $file, $l, "\/\/ comment");
         }
 
-        # check spaces after for/if/while
-        if($l =~ /^(.*)(for|if|while) \(/) {
+        my $nostr = nostrings($l);
+        # check spaces after for/if/while/function call
+        if($nostr =~ /^(.*)(for|if|while| ([a-zA-Z0-9_]+)) \((.)/) {
             if($1 =~ / *\#/) {
                 # this is a #if, treat it differently
             }
+            elsif($3 eq "return") {
+                # return must have a space
+            }
+            elsif($3 eq "case") {
+                # case must have a space
+            }
+            elsif($4 eq "*") {
+                # (* beginning makes the space OK!
+            }
+            elsif($1 =~ / *typedef/) {
+                # typedefs can use space-paren
+            }
             else {
                 checkwarn("SPACEBEFOREPAREN", $line, length($1)+length($2), $file, $l,
                           "$2 with space");
             }
         }
 
+        if($nostr =~ /^((.*)(if) *\()(.*)\)/) {
+            my $pos = length($1);
+            if($4 =~ / = /) {
+                checkwarn("ASSIGNWITHINCONDITION",
+                          $line, $pos+1, $file, $l,
+                          "assignment within conditional expression");
+            }
+        }
         # check spaces after open parentheses
         if($l =~ /^(.*[a-z])\( /i) {
             checkwarn("SPACEAFTERPAREN",
@@ -388,7 +434,7 @@ sub scanfile {
                 # There is a quote here, figure out whether the comma is
                 # within a string or '' or not.
                 if($pref =~ /\"/) {
-                    # withing a string
+                    # within a string
                 }
                 elsif($pref =~ /\'$/) {
                     # a single letter
@@ -423,6 +469,7 @@ sub scanfile {
         # scan for use of banned functions
         if($l =~ /^(.*\W)
                    (gets|
+                   strtok|
                     v?sprintf|
                     (str|_mbs|_tcs|_wcs)n?cat|
                     LoadLibrary(Ex)?(A|W)?)
@@ -470,6 +517,77 @@ sub scanfile {
             }
         }
 
+        # check for 'char * name'
+        if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost) *(\*+)) (\w+)/) && ($4 ne "const")) {
+            checkwarn("ASTERISKNOSPACE",
+                      $line, length($1), $file, $ol,
+                      "no space after declarative asterisk");
+        }
+        # check for 'char*'
+        if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) {
+            checkwarn("ASTERISKNOSPACE",
+                      $line, length($1)-1, $file, $ol,
+                      "no space before asterisk");
+        }
+
+        # check for 'void func() {', but avoid false positives by requiring
+        # both an open and closed parentheses before the open brace
+        if($l =~ /^((\w).*)\{\z/) {
+            my $k = $1;
+            $k =~ s/const *//;
+            $k =~ s/static *//;
+            if($k =~ /\(.*\)/) {
+                checkwarn("BRACEPOS",
+                          $line, length($l)-1, $file, $ol,
+                          "wrongly placed open brace");
+            }
+        }
+
+        # check for equals sign without spaces next to it
+        if($nostr =~ /(.*)\=[a-z0-9]/i) {
+            checkwarn("EQUALSNOSPACE",
+                      $line, length($1)+1, $file, $ol,
+                      "no space after equals sign");
+        }
+        # check for equals sign without spaces before it
+        elsif($nostr =~ /(.*)[a-z0-9]\=/i) {
+            checkwarn("NOSPACEEQUALS",
+                      $line, length($1)+1, $file, $ol,
+                      "no space before equals sign");
+        }
+
+        # check for plus signs without spaces next to it
+        if($nostr =~ /(.*)[^+]\+[a-z0-9]/i) {
+            checkwarn("PLUSNOSPACE",
+                      $line, length($1)+1, $file, $ol,
+                      "no space after plus sign");
+        }
+        # check for plus sign without spaces before it
+        elsif($nostr =~ /(.*)[a-z0-9]\+[^+]/i) {
+            checkwarn("NOSPACEPLUS",
+                      $line, length($1)+1, $file, $ol,
+                      "no space before plus sign");
+        }
+
+        # check for semicolons without space next to it
+        if($nostr =~ /(.*)\;[a-z0-9]/i) {
+            checkwarn("SEMINOSPACE",
+                      $line, length($1)+1, $file, $ol,
+                      "no space after semilcolon");
+        }
+
+        # check for more than one consecutive space before open brace or
+        # question mark. Skip lines containing strings since they make it hard
+        # due to artificially getting multiple spaces
+        if(($l eq $nostr) &&
+           $nostr =~ /^(.*(\S)) + [{?]/i) {
+            checkwarn("MULTISPACE",
+                      $line, length($1)+1, $file, $ol,
+                      "multiple space");
+            print STDERR "L: $l\n";
+            print STDERR "nostr: $nostr\n";
+        }
+
         $line++;
         $prevl = $ol;
     }
@@ -490,7 +608,7 @@ sub scanfile {
 
 if($errors || $warnings || $verbose) {
     printf "checksrc: %d errors and %d warnings\n", $errors, $warnings;
-    if($supressed) {
+    if($suppressed) {
         printf "checksrc: %d errors and %d warnings suppressed\n",
         $serrors,
         $swarnings;