Home | History | Annotate | Download | only in scripts
      1 #!/usr/bin/perl -w
      2 #
      3 # CDDL HEADER START
      4 #
      5 # The contents of this file are subject to the terms of the
      6 # Common Development and Distribution License (the "License").
      7 # You may not use this file except in compliance with the License.
      8 #
      9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10 # or http://www.opensolaris.org/os/licensing.
     11 # See the License for the specific language governing permissions
     12 # and limitations under the License.
     13 #
     14 # When distributing Covered Code, include this CDDL HEADER in each
     15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16 # If applicable, add the following below this CDDL HEADER, with the
     17 # fields enclosed by brackets "[]" replaced with your own identifying
     18 # information: Portions Copyright [yyyy] [name of copyright owner]
     19 #
     20 # CDDL HEADER END
     21 #
     22 #
     23 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24 # Use is subject to license terms.
     25 #
     26 # @(#)cstyle 1.58 98/09/09 (from shannon)
     27 #ident	"%Z%%M%	%I%	%E% SMI"
     28 #
     29 # cstyle - check for some common stylistic errors.
     30 #
     31 #	cstyle is a sort of "lint" for C coding style.
     32 #	It attempts to check for the style used in the
     33 #	kernel, sometimes known as "Bill Joy Normal Form".
     34 #
     35 #	There's a lot this can't check for, like proper indentation
     36 #	of code blocks.  There's also a lot more this could check for.
     37 #
     38 #	A note to the non perl literate:
     39 #
     40 #		perl regular expressions are pretty much like egrep
     41 #		regular expressions, with the following special symbols
     42 #
     43 #		\s	any space character
     44 #		\S	any non-space character
     45 #		\w	any "word" character [a-zA-Z0-9_]
     46 #		\W	any non-word character
     47 #		\d	a digit [0-9]
     48 #		\D	a non-digit
     49 #		\b	word boundary (between \w and \W)
     50 #		\B	non-word boundary
     51 #
     52 
     53 require 5.0;
     54 use IO::File;
     55 use Getopt::Std;
     56 use strict;
     57 
     58 my $usage =
     59 "usage: cstyle [-chpvCP] [-o constructs] file ...
     60 	-c	check continuation indentation inside functions
     61 	-h	perform heuristic checks that are sometimes wrong
     62 	-p	perform some of the more picky checks
     63 	-v	verbose
     64 	-C	don't check anything in header block comments
     65 	-P	check for use of non-POSIX types
     66 	-o constructs
     67 		allow a comma-seperated list of optional constructs:
     68 		    doxygen	allow doxygen-style block comments (/** /*!)
     69 		    splint	allow splint-style lint comments (/*@ ... @*/)
     70 ";
     71 
     72 my %opts;
     73 
     74 if (!getopts("cho:pvCP", \%opts)) {
     75 	print $usage;
     76 	exit 2;
     77 }
     78 
     79 my $check_continuation = $opts{'c'};
     80 my $heuristic = $opts{'h'};
     81 my $picky = $opts{'p'};
     82 my $verbose = $opts{'v'};
     83 my $ignore_hdr_comment = $opts{'C'};
     84 my $check_posix_types = $opts{'P'};
     85 
     86 my $doxygen_comments = 0;
     87 my $splint_comments = 0;
     88 
     89 if (defined($opts{'o'})) {
     90 	for my $x (split /,/, $opts{'o'}) {
     91 		if ($x eq "doxygen") {
     92 			$doxygen_comments = 1;
     93 		} elsif ($x eq "splint") {
     94 			$splint_comments = 1;
     95 		} else {
     96 			print "cstyle: unrecognized construct \"$x\"\n";
     97 			print $usage;
     98 			exit 2;
     99 		}
    100 	}
    101 }
    102 
    103 my ($filename, $line, $prev);		# shared globals
    104 
    105 my $fmt;
    106 my $hdr_comment_start;
    107 
    108 if ($verbose) {
    109 	$fmt = "%s: %d: %s\n%s\n";
    110 } else {
    111 	$fmt = "%s: %d: %s\n";
    112 }
    113 
    114 if ($doxygen_comments) {
    115 	# doxygen comments look like "/*!" or "/**"; allow them.
    116 	$hdr_comment_start = qr/^\s*\/\*[\!\*]?$/;
    117 } else {
    118 	$hdr_comment_start = qr/^\s*\/\*$/;
    119 }
    120 
    121 # Note, following must be in single quotes so that \s and \w work right.
    122 my $typename = '(int|char|short|long|unsigned|float|double' .
    123     '|\w+_t|struct\s+\w+|union\s+\w+|FILE)';
    124 
    125 # mapping of old types to POSIX compatible types
    126 my %old2posix = (
    127 	'unchar' => 'uchar_t',
    128 	'ushort' => 'ushort_t',
    129 	'uint' => 'uint_t',
    130 	'ulong' => 'ulong_t',
    131 	'u_int' => 'uint_t',
    132 	'u_short' => 'ushort_t',
    133 	'u_long' => 'ulong_t',
    134 	'u_char' => 'uchar_t',
    135 	'quad' => 'quad_t'
    136 );
    137 
    138 my $lint_re = qr/\/\*(?:
    139 	ARGSUSED[0-9]*|NOTREACHED|LINTLIBRARY|VARARGS[0-9]*|
    140 	CONSTCOND|CONSTANTCOND|CONSTANTCONDITION|EMPTY|
    141 	FALLTHRU|FALLTHROUGH|LINTED.*?|PRINTFLIKE[0-9]*|
    142 	PROTOLIB[0-9]*|SCANFLIKE[0-9]*|CSTYLED.*?
    143     )\*\//x;
    144 
    145 my $splint_re = qr/\/\*@.*?@\*\//x;
    146 
    147 my $warlock_re = qr/\/\*\s*(?:
    148 	VARIABLES\ PROTECTED\ BY|
    149 	MEMBERS\ PROTECTED\ BY|
    150 	ALL\ MEMBERS\ PROTECTED\ BY|
    151 	READ-ONLY\ VARIABLES:|
    152 	READ-ONLY\ MEMBERS:|
    153 	VARIABLES\ READABLE\ WITHOUT\ LOCK:|
    154 	MEMBERS\ READABLE\ WITHOUT\ LOCK:|
    155 	LOCKS\ COVERED\ BY|
    156 	LOCK\ UNNEEDED\ BECAUSE|
    157 	LOCK\ NEEDED:|
    158 	LOCK\ HELD\ ON\ ENTRY:|
    159 	READ\ LOCK\ HELD\ ON\ ENTRY:|
    160 	WRITE\ LOCK\ HELD\ ON\ ENTRY:|
    161 	LOCK\ ACQUIRED\ AS\ SIDE\ EFFECT:|
    162 	READ\ LOCK\ ACQUIRED\ AS\ SIDE\ EFFECT:|
    163 	WRITE\ LOCK\ ACQUIRED\ AS\ SIDE\ EFFECT:|
    164 	LOCK\ RELEASED\ AS\ SIDE\ EFFECT:|
    165 	LOCK\ UPGRADED\ AS\ SIDE\ EFFECT:|
    166 	LOCK\ DOWNGRADED\ AS\ SIDE\ EFFECT:|
    167 	FUNCTIONS\ CALLED\ THROUGH\ POINTER|
    168 	FUNCTIONS\ CALLED\ THROUGH\ MEMBER|
    169 	LOCK\ ORDER:
    170     )/x;
    171 
    172 my $err_stat = 0;		# exit status
    173 
    174 if ($#ARGV >= 0) {
    175 	foreach my $arg (@ARGV) {
    176 		my $fh = new IO::File $arg, "r";
    177 		if (!defined($fh)) {
    178 			printf "%s: can not open\n", $arg;
    179 		} else {
    180 			&cstyle($arg, $fh);
    181 			close $fh;
    182 		}
    183 	}
    184 } else {
    185 	&cstyle("<stdin>", *STDIN);
    186 }
    187 exit $err_stat;
    188 
    189 my $no_errs = 0;		# set for CSTYLED-protected lines
    190 
    191 sub err($) {
    192 	my ($error) = @_;
    193 	unless ($no_errs) {
    194 		printf $fmt, $filename, $., $error, $line;
    195 		$err_stat = 1;
    196 	}
    197 }
    198 
    199 sub err_prefix($$) {
    200 	my ($prevline, $error) = @_;
    201 	my $out = $prevline."\n".$line;
    202 	unless ($no_errs) {
    203 		printf $fmt, $filename, $., $error, $out;
    204 		$err_stat = 1;
    205 	}
    206 }
    207 
    208 sub err_prev($) {
    209 	my ($error) = @_;
    210 	unless ($no_errs) {
    211 		printf $fmt, $filename, $. - 1, $error, $prev;
    212 		$err_stat = 1;
    213 	}
    214 }
    215 
    216 sub cstyle($$) {
    217 
    218 my ($fn, $filehandle) = @_;
    219 $filename = $fn;			# share it globally
    220 
    221 my $in_cpp = 0;
    222 my $next_in_cpp = 0;
    223 
    224 my $in_comment = 0;
    225 my $in_header_comment = 0;
    226 my $comment_done = 0;
    227 my $in_warlock_comment = 0;
    228 my $in_function = 0;
    229 my $in_function_header = 0;
    230 my $in_declaration = 0;
    231 my $note_level = 0;
    232 my $nextok = 0;
    233 my $nocheck = 0;
    234 
    235 my $in_string = 0;
    236 
    237 my ($okmsg, $comment_prefix);
    238 
    239 $line = '';
    240 $prev = '';
    241 reset_indent();
    242 
    243 line: while (<$filehandle>) {
    244 	s/\r?\n$//;	# strip return and newline
    245 
    246 	# save the original line, then remove all text from within
    247 	# double or single quotes, we do not want to check such text.
    248 
    249 	$line = $_;
    250 
    251 	#
    252 	# C allows strings to be continued with a backslash at the end of
    253 	# the line.  We translate that into a quoted string on the previous
    254 	# line followed by an initial quote on the next line.
    255 	#
    256 	# (we assume that no-one will use backslash-continuation with character
    257 	# constants)
    258 	#
    259 	$_ = '"' . $_		if ($in_string && !$nocheck && !$in_comment);
    260 
    261 	#
    262 	# normal strings and characters
    263 	#
    264 	s/'([^\\']|\\[^xX0]|\\0[0-9]*|\\[xX][0-9a-fA-F]*)'/''/g;
    265 	s/"([^\\"]|\\.)*"/\"\"/g;
    266 
    267 	#
    268 	# detect string continuation
    269 	#
    270 	if ($nocheck || $in_comment) {
    271 		$in_string = 0;
    272 	} else {
    273 		#
    274 		# Now that all full strings are replaced with "", we check
    275 		# for unfinished strings continuing onto the next line.
    276 		#
    277 		$in_string =
    278 		    (s/([^"](?:"")*)"([^\\"]|\\.)*\\$/$1""/ ||
    279 		    s/^("")*"([^\\"]|\\.)*\\$/""/);
    280 	}
    281 
    282 	#
    283 	# figure out if we are in a cpp directive
    284 	#
    285 	$in_cpp = $next_in_cpp || /^\s*#/;	# continued or started
    286 	$next_in_cpp = $in_cpp && /\\$/;	# only if continued
    287 
    288 	# strip off trailing backslashes, which appear in long macros
    289 	s/\s*\\$//;
    290 
    291 	# an /* END CSTYLED */ comment ends a no-check block.
    292 	if ($nocheck) {
    293 		if (/\/\* *END *CSTYLED *\*\//) {
    294 			$nocheck = 0;
    295 		} else {
    296 			reset_indent();
    297 			next line;
    298 		}
    299 	}
    300 
    301 	# a /*CSTYLED*/ comment indicates that the next line is ok.
    302 	if ($nextok) {
    303 		if ($okmsg) {
    304 			err($okmsg);
    305 		}
    306 		$nextok = 0;
    307 		$okmsg = 0;
    308 		if (/\/\* *CSTYLED.*\*\//) {
    309 			/^.*\/\* *CSTYLED *(.*) *\*\/.*$/;
    310 			$okmsg = $1;
    311 			$nextok = 1;
    312 		}
    313 		$no_errs = 1;
    314 	} elsif ($no_errs) {
    315 		$no_errs = 0;
    316 	}
    317 
    318 	# check length of line.
    319 	# first, a quick check to see if there is any chance of being too long.
    320 	if (($line =~ tr/\t/\t/) * 7 + length($line) > 80) {
    321 		# yes, there is a chance.
    322 		# replace tabs with spaces and check again.
    323 		my $eline = $line;
    324 		1 while $eline =~
    325 		    s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
    326 		if (length($eline) > 80) {
    327 			err("line > 80 characters");
    328 		}
    329 	}
    330 
    331 	# ignore NOTE(...) annotations (assumes NOTE is on lines by itself).
    332 	if ($note_level || /\b_?NOTE\s*\(/) { # if in NOTE or this is NOTE
    333 		s/[^()]//g;			  # eliminate all non-parens
    334 		$note_level += s/\(//g - length;  # update paren nest level
    335 		next;
    336 	}
    337 
    338 	# a /* BEGIN CSTYLED */ comment starts a no-check block.
    339 	if (/\/\* *BEGIN *CSTYLED *\*\//) {
    340 		$nocheck = 1;
    341 	}
    342 
    343 	# a /*CSTYLED*/ comment indicates that the next line is ok.
    344 	if (/\/\* *CSTYLED.*\*\//) {
    345 		/^.*\/\* *CSTYLED *(.*) *\*\/.*$/;
    346 		$okmsg = $1;
    347 		$nextok = 1;
    348 	}
    349 	if (/\/\/ *CSTYLED/) {
    350 		/^.*\/\/ *CSTYLED *(.*)$/;
    351 		$okmsg = $1;
    352 		$nextok = 1;
    353 	}
    354 
    355 	# universal checks; apply to everything
    356 	if (/\t +\t/) {
    357 		err("spaces between tabs");
    358 	}
    359 	if (/ \t+ /) {
    360 		err("tabs between spaces");
    361 	}
    362 	if (/\s$/) {
    363 		err("space or tab at end of line");
    364 	}
    365 	if (/[^ \t(]\/\*/ && !/\w\(\/\*.*\*\/\);/) {
    366 		err("comment preceded by non-blank");
    367 	}
    368 
    369 	# is this the beginning or ending of a function?
    370 	# (not if "struct foo\n{\n")
    371 	if (/^{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
    372 		$in_function = 1;
    373 		$in_declaration = 1;
    374 		$in_function_header = 0;
    375 		$prev = $line;
    376 		next line;
    377 	}
    378 	if (/^}\s*(\/\*.*\*\/\s*)*$/) {
    379 		if ($prev =~ /^\s*return\s*;/) {
    380 			err_prev("unneeded return at end of function");
    381 		}
    382 		$in_function = 0;
    383 		reset_indent();		# we don't check between functions
    384 		$prev = $line;
    385 		next line;
    386 	}
    387 	if (/^\w*\($/) {
    388 		$in_function_header = 1;
    389 	}
    390 
    391 	if ($in_warlock_comment && /\*\//) {
    392 		$in_warlock_comment = 0;
    393 		$prev = $line;
    394 		next line;
    395 	}
    396 
    397 	# a blank line terminates the declarations within a function.
    398 	# XXX - but still a problem in sub-blocks.
    399 	if ($in_declaration && /^$/) {
    400 		$in_declaration = 0;
    401 	}
    402 
    403 	if ($comment_done) {
    404 		$in_comment = 0;
    405 		$in_header_comment = 0;
    406 		$comment_done = 0;
    407 	}
    408 	# does this looks like the start of a block comment?
    409 	if (/$hdr_comment_start/) {
    410 		if (!/^\t*\/\*/) {
    411 			err("block comment not indented by tabs");
    412 		}
    413 		$in_comment = 1;
    414 		/^(\s*)\//;
    415 		$comment_prefix = $1;
    416 		if ($comment_prefix eq "") {
    417 			$in_header_comment = 1;
    418 		}
    419 		$prev = $line;
    420 		next line;
    421 	}
    422 	# are we still in the block comment?
    423 	if ($in_comment) {
    424 		if (/^$comment_prefix \*\/$/) {
    425 			$comment_done = 1;
    426 		} elsif (/\*\//) {
    427 			$comment_done = 1;
    428 			err("improper block comment close")
    429 			    unless ($ignore_hdr_comment && $in_header_comment);
    430 		} elsif (!/^$comment_prefix \*[ \t]/ &&
    431 		    !/^$comment_prefix \*$/) {
    432 			err("improper block comment")
    433 			    unless ($ignore_hdr_comment && $in_header_comment);
    434 		}
    435 	}
    436 
    437 	if ($in_header_comment && $ignore_hdr_comment) {
    438 		$prev = $line;
    439 		next line;
    440 	}
    441 
    442 	# check for errors that might occur in comments and in code.
    443 
    444 	# allow spaces to be used to draw pictures in header comments.
    445 	if (/[^ ]     / && !/".*     .*"/ && !$in_header_comment) {
    446 		err("spaces instead of tabs");
    447 	}
    448 	if (/^ / && !/^ \*[ \t\/]/ && !/^ \*$/ &&
    449 	    (!/^    \w/ || $in_function != 0)) {
    450 		err("indent by spaces instead of tabs");
    451 	}
    452 	if (/^\t+ [^ \t\*]/ || /^\t+  \S/ || /^\t+   \S/) {
    453 		err("continuation line not indented by 4 spaces");
    454 	}
    455 	if (/$warlock_re/ && !/\*\//) {
    456 		$in_warlock_comment = 1;
    457 		$prev = $line;
    458 		next line;
    459 	}
    460 	if (/^\s*\/\*./ && !/^\s*\/\*.*\*\// && !/$hdr_comment_start/) {
    461 		err("improper first line of block comment");
    462 	}
    463 
    464 	if ($in_comment) {	# still in comment, don't do further checks
    465 		$prev = $line;
    466 		next line;
    467 	}
    468 
    469 	if ((/[^(]\/\*\S/ || /^\/\*\S/) &&
    470 	    !(/$lint_re/ || ($splint_comments && /$splint_re/))) {
    471 		err("missing blank after open comment");
    472 	}
    473 	if (/\S\*\/[^)]|\S\*\/$/ &&
    474 	    !(/$lint_re/ || ($splint_comments && /$splint_re/))) {
    475 		err("missing blank before close comment");
    476 	}
    477 	if (/\/\/\S/) {		# C++ comments
    478 		err("missing blank after start comment");
    479 	}
    480 	# check for unterminated single line comments, but allow them when
    481 	# they are used to comment out the argument list of a function
    482 	# declaration.
    483 	if (/\S.*\/\*/ && !/\S.*\/\*.*\*\// && !/\(\/\*/) {
    484 		err("unterminated single line comment");
    485 	}
    486 
    487 	if (/^(#else|#endif|#include)(.*)$/) {
    488 		$prev = $line;
    489 		if ($picky) {
    490 			my $directive = $1;
    491 			my $clause = $2;
    492 			# Enforce ANSI rules for #else and #endif: no noncomment
    493 			# identifiers are allowed after #endif or #else.  Allow
    494 			# C++ comments since they seem to be a fact of life.
    495 			if ((($1 eq "#endif") || ($1 eq "#else")) &&
    496 			    ($clause ne "") &&
    497 			    (!($clause =~ /^\s+\/\*.*\*\/$/)) &&
    498 			    (!($clause =~ /^\s+\/\/.*$/))) {
    499 				err("non-comment text following " .
    500 				    "$directive (or malformed $directive " .
    501 				    "directive)");
    502 			}
    503 		}
    504 		next line;
    505 	}
    506 
    507 	#
    508 	# delete any comments and check everything else.  Note that
    509 	# ".*?" is a non-greedy match, so that we don't get confused by
    510 	# multiple comments on the same line.
    511 	#
    512 	s/\/\*.*?\*\///g;
    513 	s/\/\/.*$//;		# C++ comments
    514 
    515 	# delete any trailing whitespace; we have already checked for that.
    516 	s/\s*$//;
    517 
    518 	# following checks do not apply to text in comments.
    519 
    520 	if (/[^<>\s][!<>=]=/ || /[^<>][!<>=]=[^\s,]/ ||
    521 	    (/[^->]>[^,=>\s]/ && !/[^->]>$/) ||
    522 	    (/[^<]<[^,=<\s]/ && !/[^<]<$/) ||
    523 	    /[^<\s]<[^<]/ || /[^->\s]>[^>]/) {
    524 		err("missing space around relational operator");
    525 	}
    526 	if (/\S>>=/ || /\S<<=/ || />>=\S/ || /<<=\S/ || /\S[-+*\/&|^%]=/ ||
    527 	    (/[^-+*\/&|^%!<>=\s]=[^=]/ && !/[^-+*\/&|^%!<>=\s]=$/) ||
    528 	    (/[^!<>=]=[^=\s]/ && !/[^!<>=]=$/)) {
    529 		# XXX - should only check this for C++ code
    530 		# XXX - there are probably other forms that should be allowed
    531 		if (!/\soperator=/) {
    532 			err("missing space around assignment operator");
    533 		}
    534 	}
    535 	if (/[,;]\S/ && !/\bfor \(;;\)/) {
    536 		err("comma or semicolon followed by non-blank");
    537 	}
    538 	# allow "for" statements to have empty "while" clauses
    539 	if (/\s[,;]/ && !/^[\t]+;$/ && !/^\s*for \([^;]*; ;[^;]*\)/) {
    540 		err("comma or semicolon preceded by blank");
    541 	}
    542 	if (/^\s*(&&|\|\|)/) {
    543 		err("improper boolean continuation");
    544 	}
    545 	if (/\S   *(&&|\|\|)/ || /(&&|\|\|)   *\S/) {
    546 		err("more than one space around boolean operator");
    547 	}
    548 	if (/\b(for|if|while|switch|sizeof|return|case)\(/) {
    549 		err("missing space between keyword and paren");
    550 	}
    551 	if (/(\b(for|if|while|switch|return)\b.*){2,}/ && !/^#define/) {
    552 		# multiple "case" and "sizeof" allowed
    553 		err("more than one keyword on line");
    554 	}
    555 	if (/\b(for|if|while|switch|sizeof|return|case)\s\s+\(/ &&
    556 	    !/^#if\s+\(/) {
    557 		err("extra space between keyword and paren");
    558 	}
    559 	# try to detect "func (x)" but not "if (x)" or
    560 	# "#define foo (x)" or "int (*func)();"
    561 	if (/\w\s\(/) {
    562 		my $s = $_;
    563 		# strip off all keywords on the line
    564 		s/\b(for|if|while|switch|return|case|sizeof)\s\(/XXX(/g;
    565 		s/#elif\s\(/XXX(/g;
    566 		s/^#define\s+\w+\s+\(/XXX(/;
    567 		# do not match things like "void (*f)();"
    568 		# or "typedef void (func_t)();"
    569 		s/\w\s\(+\*/XXX(*/g;
    570 		s/\b($typename|void)\s+\(+/XXX(/og;
    571 		if (/\w\s\(/) {
    572 			err("extra space between function name and left paren");
    573 		}
    574 		$_ = $s;
    575 	}
    576 	# try to detect "int foo(x)", but not "extern int foo(x);"
    577 	# XXX - this still trips over too many legitimate things,
    578 	# like "int foo(x,\n\ty);"
    579 #		if (/^(\w+(\s|\*)+)+\w+\(/ && !/\)[;,](\s|)*$/ &&
    580 #		    !/^(extern|static)\b/) {
    581 #			err("return type of function not on separate line");
    582 #		}
    583 	# this is a close approximation
    584 	if (/^(\w+(\s|\*)+)+\w+\(.*\)(\s|)*$/ &&
    585 	    !/^(extern|static)\b/) {
    586 		err("return type of function not on separate line");
    587 	}
    588 	if (/^#define /) {
    589 		err("#define followed by space instead of tab");
    590 	}
    591 	if (/^\s*return\W[^;]*;/ && !/^\s*return\s*\(.*\);/) {
    592 		err("unparenthesized return expression");
    593 	}
    594 	if (/\bsizeof\b/ && !/\bsizeof\s*\(.*\)/) {
    595 		err("unparenthesized sizeof expression");
    596 	}
    597 	if (/\(\s/) {
    598 		err("whitespace after left paren");
    599 	}
    600 	# allow "for" statements to have empty "continue" clauses
    601 	if (/\s\)/ && !/^\s*for \([^;]*;[^;]*; \)/) {
    602 		err("whitespace before right paren");
    603 	}
    604 	if (/^\s*\(void\)[^ ]/) {
    605 		err("missing space after (void) cast");
    606 	}
    607 	if (/\S{/ && !/{{/) {
    608 		err("missing space before left brace");
    609 	}
    610 	if ($in_function && /^\s+{/ &&
    611 	    ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
    612 		err("left brace starting a line");
    613 	}
    614 	if (/}(else|while)/) {
    615 		err("missing space after right brace");
    616 	}
    617 	if (/}\s\s+(else|while)/) {
    618 		err("extra space after right brace");
    619 	}
    620 	if (/\b_VOID\b|\bVOID\b|\bSTATIC\b/) {
    621 		err("obsolete use of VOID or STATIC");
    622 	}
    623 	if (/\b$typename\*/o) {
    624 		err("missing space between type name and *");
    625 	}
    626 	if (/^\s+#/) {
    627 		err("preprocessor statement not in column 1");
    628 	}
    629 	if (/^#\s/) {
    630 		err("blank after preprocessor #");
    631 	}
    632 	if (/!\s*(strcmp|strncmp|bcmp)\s*\(/) {
    633 		err("don't use boolean ! with comparison functions");
    634 	}
    635 
    636 	#
    637 	# We completely ignore, for purposes of indentation:
    638 	#  * lines outside of functions
    639 	#  * preprocessor lines
    640 	#
    641 	if ($check_continuation && $in_function && !$in_cpp) {
    642 		process_indent($_);
    643 	}
    644 	if ($picky) {
    645 		# try to detect spaces after casts, but allow (e.g.)
    646 		# "sizeof (int) + 1", "void (*funcptr)(int) = foo;", and
    647 		# "int foo(int) __NORETURN;"
    648 		if ((/^\($typename( \*+)?\)\s/o ||
    649 		    /\W\($typename( \*+)?\)\s/o) &&
    650 		    !/sizeof\s*\($typename( \*)?\)\s/o &&
    651 		    !/\($typename( \*+)?\)\s+=[^=]/o) {
    652 			err("space after cast");
    653 		}
    654 		if (/\b$typename\s*\*\s/o &&
    655 		    !/\b$typename\s*\*\s+const\b/o) {
    656 			err("unary * followed by space");
    657 		}
    658 	}
    659 	if ($check_posix_types) {
    660 		# try to detect old non-POSIX types.
    661 		# POSIX requires all non-standard typedefs to end in _t,
    662 		# but historically these have been used.
    663 		if (/\b(unchar|ushort|uint|ulong|u_int|u_short|u_long|u_char|quad)\b/) {
    664 			err("non-POSIX typedef $1 used: use $old2posix{$1} instead");
    665 		}
    666 	}
    667 	if ($heuristic) {
    668 		# cannot check this everywhere due to "struct {\n...\n} foo;"
    669 		if ($in_function && !$in_declaration &&
    670 		    /}./ && !/}\s+=/ && !/{.*}[;,]$/ && !/}(\s|)*$/ &&
    671 		    !/} (else|while)/ && !/}}/) {
    672 			err("possible bad text following right brace");
    673 		}
    674 		# cannot check this because sub-blocks in
    675 		# the middle of code are ok
    676 		if ($in_function && /^\s+{/) {
    677 			err("possible left brace starting a line");
    678 		}
    679 	}
    680 	if (/^\s*else\W/) {
    681 		if ($prev =~ /^\s*}$/) {
    682 			err_prefix($prev,
    683 			    "else and right brace should be on same line");
    684 		}
    685 	}
    686 	$prev = $line;
    687 }
    688 
    689 if ($prev eq "") {
    690 	err("last line in file is blank");
    691 }
    692 
    693 }
    694 
    695 #
    696 # Continuation-line checking
    697 #
    698 # The rest of this file contains the code for the continuation checking
    699 # engine.  It's a pretty simple state machine which tracks the expression
    700 # depth (unmatched '('s and '['s).
    701 #
    702 # Keep in mind that the argument to process_indent() has already been heavily
    703 # processed; all comments have been replaced by control-A, and the contents of
    704 # strings and character constants have been elided.
    705 #
    706 
    707 my $cont_in;		# currently inside of a continuation
    708 my $cont_off;		# skipping an initializer or definition
    709 my $cont_noerr;		# suppress cascading errors
    710 my $cont_start;		# the line being continued
    711 my $cont_base;		# the base indentation
    712 my $cont_first;		# this is the first line of a statement
    713 my $cont_multiseg;	# this continuation has multiple segments
    714 
    715 my $cont_special;	# this is a C statement (if, for, etc.)
    716 my $cont_macro;		# this is a macro
    717 my $cont_case;		# this is a multi-line case
    718 
    719 my @cont_paren;		# the stack of unmatched ( and [s we've seen
    720 
    721 sub
    722 reset_indent()
    723 {
    724 	$cont_in = 0;
    725 	$cont_off = 0;
    726 }
    727 
    728 sub
    729 delabel($)
    730 {
    731 	#
    732 	# replace labels with tabs.  Note that there may be multiple
    733 	# labels on a line.
    734 	#
    735 	local $_ = $_[0];
    736 
    737 	while (/^(\t*)( *(?:(?:\w+\s*)|(?:case\b[^:]*)): *)(.*)$/) {
    738 		my ($pre_tabs, $label, $rest) = ($1, $2, $3);
    739 		$_ = $pre_tabs;
    740 		while ($label =~ s/^([^\t]*)(\t+)//) {
    741 			$_ .= "\t" x (length($2) + length($1) / 8);
    742 		}
    743 		$_ .= ("\t" x (length($label) / 8)).$rest;
    744 	}
    745 
    746 	return ($_);
    747 }
    748 
    749 sub
    750 process_indent($)
    751 {
    752 	require strict;
    753 	local $_ = $_[0];			# preserve the global $_
    754 
    755 	s///g;	# No comments
    756 	s/\s+$//;	# Strip trailing whitespace
    757 
    758 	return			if (/^$/);	# skip empty lines
    759 
    760 	# regexps used below; keywords taking (), macros, and continued cases
    761 	my $special = '(?:(?:\}\s*)?else\s+)?(?:if|for|while|switch)\b';
    762 	my $macro = '[A-Z_][A-Z_0-9]*\(';
    763 	my $case = 'case\b[^:]*$';
    764 
    765 	# skip over enumerations, array definitions, initializers, etc.
    766 	if ($cont_off <= 0 && !/^\s*$special/ &&
    767 	    (/(?:(?:\b(?:enum|struct|union)\s*[^\{]*)|(?:\s+=\s*)){/ ||
    768 	    (/^\s*{/ && $prev =~ /=\s*(?:\/\*.*\*\/\s*)*$/))) {
    769 		$cont_in = 0;
    770 		$cont_off = tr/{/{/ - tr/}/}/;
    771 		return;
    772 	}
    773 	if ($cont_off) {
    774 		$cont_off += tr/{/{/ - tr/}/}/;
    775 		return;
    776 	}
    777 
    778 	if (!$cont_in) {
    779 		$cont_start = $line;
    780 
    781 		if (/^\t* /) {
    782 			err("non-continuation indented 4 spaces");
    783 			$cont_noerr = 1;		# stop reporting
    784 		}
    785 		$_ = delabel($_);	# replace labels with tabs
    786 
    787 		# check if the statement is complete
    788 		return		if (/^\s*\}?$/);
    789 		return		if (/^\s*\}?\s*else\s*\{?$/);
    790 		return		if (/^\s*do\s*\{?$/);
    791 		return		if (/{$/);
    792 		return		if (/}[,;]?$/);
    793 
    794 		# Allow macros on their own lines
    795 		return		if (/^\s*[A-Z_][A-Z_0-9]*$/);
    796 
    797 		# cases we don't deal with, generally non-kosher
    798 		if (/{/) {
    799 			err("stuff after {");
    800 			return;
    801 		}
    802 
    803 		# Get the base line, and set up the state machine
    804 		/^(\t*)/;
    805 		$cont_base = $1;
    806 		$cont_in = 1;
    807 		@cont_paren = ();
    808 		$cont_first = 1;
    809 		$cont_multiseg = 0;
    810 
    811 		# certain things need special processing
    812 		$cont_special = /^\s*$special/? 1 : 0;
    813 		$cont_macro = /^\s*$macro/? 1 : 0;
    814 		$cont_case = /^\s*$case/? 1 : 0;
    815 	} else {
    816 		$cont_first = 0;
    817 
    818 		# Strings may be pulled back to an earlier (half-)tabstop
    819 		unless ($cont_noerr || /^$cont_base    / ||
    820 		    (/^\t*(?:    )?(?:gettext\()?\"/ && !/^$cont_base\t/)) {
    821 			err_prefix($cont_start,
    822 			    "continuation should be indented 4 spaces");
    823 		}
    824 	}
    825 
    826 	my $rest = $_;			# keeps the remainder of the line
    827 
    828 	#
    829 	# The split matches 0 characters, so that each 'special' character
    830 	# is processed separately.  Parens and brackets are pushed and
    831 	# popped off the @cont_paren stack.  For normal processing, we wait
    832 	# until a ; or { terminates the statement.  "special" processing
    833 	# (if/for/while/switch) is allowed to stop when the stack empties,
    834 	# as is macro processing.  Case statements are terminated with a :
    835 	# and an empty paren stack.
    836 	#
    837 	foreach $_ (split /[^\(\)\[\]\{\}\;\:]*/) {
    838 		next		if (length($_) == 0);
    839 
    840 		# rest contains the remainder of the line
    841 		my $rxp = "[^\Q$_\E]*\Q$_\E";
    842 		$rest =~ s/^$rxp//;
    843 
    844 		if (/\(/ || /\[/) {
    845 			push @cont_paren, $_;
    846 		} elsif (/\)/ || /\]/) {
    847 			my $cur = $_;
    848 			tr/\)\]/\(\[/;
    849 
    850 			my $old = (pop @cont_paren);
    851 			if (!defined($old)) {
    852 				err("unexpected '$cur'");
    853 				$cont_in = 0;
    854 				last;
    855 			} elsif ($old ne $_) {
    856 				err("'$cur' mismatched with '$old'");
    857 				$cont_in = 0;
    858 				last;
    859 			}
    860 
    861 			#
    862 			# If the stack is now empty, do special processing
    863 			# for if/for/while/switch and macro statements.
    864 			#
    865 			next		if (@cont_paren != 0);
    866 			if ($cont_special) {
    867 				if ($rest =~ /^\s*{?$/) {
    868 					$cont_in = 0;
    869 					last;
    870 				}
    871 				if ($rest =~ /^\s*;$/) {
    872 					err("empty if/for/while body ".
    873 					    "not on its own line");
    874 					$cont_in = 0;
    875 					last;
    876 				}
    877 				if (!$cont_first && $cont_multiseg == 1) {
    878 					err_prefix($cont_start,
    879 					    "multiple statements continued ".
    880 					    "over multiple lines");
    881 					$cont_multiseg = 2;
    882 				} elsif ($cont_multiseg == 0) {
    883 					$cont_multiseg = 1;
    884 				}
    885 				# We've finished this section, start
    886 				# processing the next.
    887 				goto section_ended;
    888 			}
    889 			if ($cont_macro) {
    890 				if ($rest =~ /^$/) {
    891 					$cont_in = 0;
    892 					last;
    893 				}
    894 			}
    895 		} elsif (/\;/) {
    896 			if ($cont_case) {
    897 				err("unexpected ;");
    898 			} elsif (!$cont_special) {
    899 				err("unexpected ;")	if (@cont_paren != 0);
    900 				if (!$cont_first && $cont_multiseg == 1) {
    901 					err_prefix($cont_start,
    902 					    "multiple statements continued ".
    903 					    "over multiple lines");
    904 					$cont_multiseg = 2;
    905 				} elsif ($cont_multiseg == 0) {
    906 					$cont_multiseg = 1;
    907 				}
    908 				if ($rest =~ /^$/) {
    909 					$cont_in = 0;
    910 					last;
    911 				}
    912 				if ($rest =~ /^\s*special/) {
    913 					err("if/for/while/switch not started ".
    914 					    "on its own line");
    915 				}
    916 				goto section_ended;
    917 			}
    918 		} elsif (/\{/) {
    919 			err("{ while in parens/brackets") if (@cont_paren != 0);
    920 			err("stuff after {")		if ($rest =~ /[^\s}]/);
    921 			$cont_in = 0;
    922 			last;
    923 		} elsif (/\}/) {
    924 			err("} while in parens/brackets") if (@cont_paren != 0);
    925 			if (!$cont_special && $rest !~ /^\s*(while|else)\b/) {
    926 				if ($rest =~ /^$/) {
    927 					err("unexpected }");
    928 				} else {
    929 					err("stuff after }");
    930 				}
    931 				$cont_in = 0;
    932 				last;
    933 			}
    934 		} elsif (/\:/ && $cont_case && @cont_paren == 0) {
    935 			err("stuff after multi-line case") if ($rest !~ /$^/);
    936 			$cont_in = 0;
    937 			last;
    938 		}
    939 		next;
    940 section_ended:
    941 		# End of a statement or if/while/for loop.  Reset
    942 		# cont_special and cont_macro based on the rest of the
    943 		# line.
    944 		$cont_special = ($rest =~ /^\s*$special/)? 1 : 0;
    945 		$cont_macro = ($rest =~ /^\s*$macro/)? 1 : 0;
    946 		$cont_case = 0;
    947 		next;
    948 	}
    949 	$cont_noerr = 0			if (!$cont_in);
    950 }
    951