]> git.proxmox.com Git - mirror_zfs.git/blobdiff - scripts/cstyle.pl
ZTS: normalize on use of `sync_pool` and `sync_all_pools`
[mirror_zfs.git] / scripts / cstyle.pl
index 7baf2554530e90cd8857e0f029911fd7ef421978..d19718ecf443a1591fb414c4db79f46f5dea4cca 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
 #
 # CDDL HEADER START
 #
@@ -19,6 +19,7 @@
 #
 # CDDL HEADER END
 #
+# Copyright 2016 Nexenta Systems, Inc.
 #
 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 require 5.0;
+use warnings;
 use IO::File;
 use Getopt::Std;
 use strict;
 
 my $usage =
-"usage: cstyle [-chpvCP] [-o constructs] file ...
+"usage: cstyle [-cghpvCP] [-o constructs] file ...
        -c      check continuation indentation inside functions
+       -g      print github actions' workflow commands
        -h      perform heuristic checks that are sometimes wrong
        -p      perform some of the more picky checks
        -v      verbose
        -C      don't check anything in header block comments
        -P      check for use of non-POSIX types
        -o constructs
-               allow a comma-seperated list of optional constructs:
+               allow a comma-separated list of optional constructs:
                    doxygen     allow doxygen-style block comments (/** /*!)
                    splint      allow splint-style lint comments (/*@ ... @*/)
 ";
 
 my %opts;
 
-if (!getopts("cho:pvCP", \%opts)) {
+if (!getopts("cgho:pvCP", \%opts)) {
        print $usage;
        exit 2;
 }
 
 my $check_continuation = $opts{'c'};
+my $github_workflow = $opts{'g'} || $ENV{'CI'};
 my $heuristic = $opts{'h'};
 my $picky = $opts{'p'};
 my $verbose = $opts{'v'};
@@ -195,7 +199,10 @@ sub err($) {
                        printf $fmt, $filename, $., $error, $line;
                } else {
                        printf $fmt, $filename, $., $error;
-               }       
+               }
+               if ($github_workflow) {
+                       printf "::error file=%s,line=%s::%s\n", $filename, $., $error;
+               }
                $err_stat = 1;
        }
 }
@@ -239,6 +246,7 @@ my $comment_done = 0;
 my $in_warlock_comment = 0;
 my $in_function = 0;
 my $in_function_header = 0;
+my $function_header_full_indent = 0;
 my $in_declaration = 0;
 my $note_level = 0;
 my $nextok = 0;
@@ -380,14 +388,15 @@ line: while (<$filehandle>) {
 
        # is this the beginning or ending of a function?
        # (not if "struct foo\n{\n")
-       if (/^{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
+       if (/^\{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
                $in_function = 1;
                $in_declaration = 1;
                $in_function_header = 0;
+               $function_header_full_indent = 0;
                $prev = $line;
                next line;
        }
-       if (/^}\s*(\/\*.*\*\/\s*)*$/) {
+       if (/^\}\s*(\/\*.*\*\/\s*)*$/) {
                if ($prev =~ /^\s*return\s*;/) {
                        err_prev("unneeded return at end of function");
                }
@@ -396,8 +405,54 @@ line: while (<$filehandle>) {
                $prev = $line;
                next line;
        }
-       if (/^\w*\($/) {
+       if ($in_function_header && ! /^    (\w|\.)/ ) {
+               if (/^\{\}$/ # empty functions
+               || /;/ #run function with multiline arguments
+               || /#/ #preprocessor commands
+               || /^[^\s\\]*\(.*\)$/ #functions without ; at the end
+               || /^$/ #function declaration can't have empty line
+               ) {
+                       $in_function_header = 0;
+                       $function_header_full_indent = 0;
+               } elsif ($prev =~ /^__attribute__/) { #__attribute__((*))
+                       $in_function_header = 0;
+                       $function_header_full_indent = 0;
+                       $prev = $line;
+                       next line;
+               } elsif ($picky && ! (/^\t/ && $function_header_full_indent != 0)) {
+
+                       err("continuation line should be indented by 4 spaces");
+               }
+       }
+
+       #
+       # If this matches something of form "foo(", it's probably a function
+       # definition, unless it ends with ") bar;", in which case it's a declaration
+       # that uses a macro to generate the type.
+       #
+       if (/^\w+\(/ && !/\) \w+;/) {
                $in_function_header = 1;
+               if (/\($/) {
+                       $function_header_full_indent = 1;
+               }
+       }
+       if ($in_function_header && /^\{$/) {
+               $in_function_header = 0;
+               $function_header_full_indent = 0;
+               $in_function = 1;
+       }
+       if ($in_function_header && /\);$/) {
+               $in_function_header = 0;
+               $function_header_full_indent = 0;
+       }
+       if ($in_function_header && /\{$/ ) {
+               if ($picky) {
+                       err("opening brace on same line as function header");
+               }
+               $in_function_header = 0;
+               $function_header_full_indent = 0;
+               $in_function = 1;
+               next line;
        }
 
        if ($in_warlock_comment && /\*\//) {
@@ -458,7 +513,7 @@ line: while (<$filehandle>) {
                err("spaces instead of tabs");
        }
        if (/^ / && !/^ \*[ \t\/]/ && !/^ \*$/ &&
-           (!/^    \w/ || $in_function != 0)) {
+           (!/^    (\w|\.)/ || $in_function != 0)) {
                err("indent by spaces instead of tabs");
        }
        if (/^\t+ [^ \t\*]/ || /^\t+  \S/ || /^\t+   \S/) {
@@ -620,14 +675,14 @@ line: while (<$filehandle>) {
        if (/\S\{/ && !/\{\{/) {
                err("missing space before left brace");
        }
-       if ($in_function && /^\s+{/ &&
+       if ($in_function && /^\s+\{/ &&
            ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
                err("left brace starting a line");
        }
-       if (/}(else|while)/) {
+       if (/\}(else|while)/) {
                err("missing space after right brace");
        }
-       if (/}\s\s+(else|while)/) {
+       if (/\}\s\s+(else|while)/) {
                err("extra space after right brace");
        }
        if (/\b_VOID\b|\bVOID\b|\bSTATIC\b/) {
@@ -680,18 +735,18 @@ line: while (<$filehandle>) {
        if ($heuristic) {
                # cannot check this everywhere due to "struct {\n...\n} foo;"
                if ($in_function && !$in_declaration &&
-                   /}./ && !/}\s+=/ && !/{.*}[;,]$/ && !/}(\s|\ 1)*$/ &&
-                   !/} (else|while)/ && !/}}/) {
+                   /\}./ && !/\}\s+=/ && !/\{.*\}[;,]$/ && !/\}(\s|\ 1)*$/ &&
+                   !/\} (else|while)/ && !/\}\}/) {
                        err("possible bad text following right brace");
                }
                # cannot check this because sub-blocks in
                # the middle of code are ok
-               if ($in_function && /^\s+{/) {
+               if ($in_function && /^\s+\{/) {
                        err("possible left brace starting a line");
                }
        }
        if (/^\s*else\W/) {
-               if ($prev =~ /^\s*}$/) {
+               if ($prev =~ /^\s*\}$/) {
                        err_prefix($prev,
                            "else and right brace should be on same line");
                }
@@ -777,8 +832,8 @@ process_indent($)
 
        # skip over enumerations, array definitions, initializers, etc.
        if ($cont_off <= 0 && !/^\s*$special/ &&
-           (/(?:(?:\b(?:enum|struct|union)\s*[^\{]*)|(?:\s+=\s*)){/ ||
-           (/^\s*{/ && $prev =~ /=\s*(?:\/\*.*\*\/\s*)*$/))) {
+           (/(?:(?:\b(?:enum|struct|union)\s*[^\{]*)|(?:\s+=\s*))\{/ ||
+           (/^\s*\{/ && $prev =~ /=\s*(?:\/\*.*\*\/\s*)*$/))) {
                $cont_in = 0;
                $cont_off = tr/{/{/ - tr/}/}/;
                return;
@@ -801,14 +856,14 @@ process_indent($)
                return          if (/^\s*\}?$/);
                return          if (/^\s*\}?\s*else\s*\{?$/);
                return          if (/^\s*do\s*\{?$/);
-               return          if (/{$/);
-               return          if (/}[,;]?$/);
+               return          if (/\{$/);
+               return          if (/\}[,;]?$/);
 
                # Allow macros on their own lines
                return          if (/^\s*[A-Z_][A-Z_0-9]*$/);
 
                # cases we don't deal with, generally non-kosher
-               if (/{/) {
+               if (/\{/) {
                        err("stuff after {");
                        return;
                }
@@ -877,7 +932,7 @@ process_indent($)
                        #
                        next            if (@cont_paren != 0);
                        if ($cont_special) {
-                               if ($rest =~ /^\s*{?$/) {
+                               if ($rest =~ /^\s*\{?$/) {
                                        $cont_in = 0;
                                        last;
                                }