-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# CDDL HEADER START
#
#
# 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 $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;
# 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");
}
$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 && /\*\//) {
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/) {
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/) {
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");
}
# 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;
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;
}
#
next if (@cont_paren != 0);
if ($cont_special) {
- if ($rest =~ /^\s*{?$/) {
+ if ($rest =~ /^\s*\{?$/) {
$cont_in = 0;
last;
}