Skip to content
Snippets Groups Projects
checkpatch.pl 68.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • 		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
    
    		    $line !~ /for\s*\(.*;\s+\)/ &&
    		    $line !~ /:\s+\)/) {
    
    			ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr);
    
    #goto labels aren't indented, allow a single space however
    
    		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
    
    		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
    
    			WARN("labels should not be indented\n" . $herecurr);
    
    # Return is not a function.
    		if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) {
    			my $spacing = $1;
    			my $value = $2;
    
    
    			# Flatten any parentheses
    
    			while ($value =~ s/\[[^\{\}]*\]/1/ ||
    			       $value !~ /(?:$Ident|-?$Constant)\s*
    					     $Compare\s*
    					     (?:$Ident|-?$Constant)/x &&
    			       $value =~ s/\([^\(\)]*\)/1/) {
    
    			}
    
    			if ($value =~ /^(?:$Ident|-?$Constant)$/) {
    				ERROR("return is not a function, parentheses are not required\n" . $herecurr);
    
    			} elsif ($spacing !~ /\s+/) {
    				ERROR("space required before the open parenthesis '('\n" . $herecurr);
    			}
    		}
    
    
    # Need a space before open parenthesis after if, while etc
    
    		if ($line=~/\b(if|while|for|switch)\(/) {
    
    			ERROR("space required before the open parenthesis '('\n" . $herecurr);
    
    # Check for illegal assignment in if conditional -- and check for trailing
    # statements after the conditional.
    
    		if ($line =~ /do\s*(?!{)/) {
    			my ($stat_next) = ctx_statement_block($line_nr_next,
    						$remain_next, $off_next);
    			$stat_next =~ s/\n./\n /g;
    			##print "stat<$stat> stat_next<$stat_next>\n";
    
    			if ($stat_next =~ /^\s*while\b/) {
    				# If the statement carries leading newlines,
    				# then count those as offsets.
    				my ($whitespace) =
    					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
    				my $offset =
    					statement_rawlines($whitespace) - 1;
    
    				$suppress_whiletrailers{$line_nr_next +
    								$offset} = 1;
    			}
    		}
    		if (!defined $suppress_whiletrailers{$linenr} &&
    		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
    
    			my ($s, $c) = ($stat, $cond);
    
    			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
    
    				ERROR("do not use assignment in if condition\n" . $herecurr);
    
    			}
    
    			# Find out what is on the end of the line after the
    			# conditional.
    
    			substr($s, 0, length($c), '');
    
    			$s =~ s/\n.*//g;
    
    			$s =~ s/$;//g; 	# Remove any comments
    
    			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
    			    $c !~ /}\s*while\s*/)
    
    				# Find out how long the conditional actually is.
    				my @newlines = ($c =~ /\n/gs);
    				my $cond_lines = 1 + $#newlines;
    
    				my $stat_real = raw_line($linenr, $cond_lines);
    				if (defined($stat_real) && $cond_lines > 1) {
    					$stat_real = "[...]\n$stat_real";
    				}
    
    				ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real);
    
    # Check for bitwise tests written as boolean
    		if ($line =~ /
    			(?:
    				(?:\[|\(|\&\&|\|\|)
    				\s*0[xX][0-9]+\s*
    				(?:\&\&|\|\|)
    			|
    				(?:\&\&|\|\|)
    				\s*0[xX][0-9]+\s*
    				(?:\&\&|\|\||\)|\])
    			)/x)
    		{
    			WARN("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
    		}
    
    
    # if and else should not have general statements after it
    
    		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
    			my $s = $1;
    			$s =~ s/$;//g; 	# Remove any comments
    			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
    				ERROR("trailing statements should be on next line\n" . $herecurr);
    			}
    
    # if should not continue a brace
    		if ($line =~ /}\s*if\b/) {
    			ERROR("trailing statements should be on next line\n" .
    				$herecurr);
    		}
    
    # case and default should not have general statements after them
    		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
    		    $line !~ /\G(?:
    
    			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
    
    			\s*return\s+
    		    )/xg)
    		{
    			ERROR("trailing statements should be on next line\n" . $herecurr);
    		}
    
    
    		# Check for }<nl>else {, these must be at the same
    		# indent level to be relevant to each other.
    		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
    						$previndent == $indent) {
    
    			ERROR("else should follow close brace '}'\n" . $hereprev);
    
    		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
    						$previndent == $indent) {
    			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
    
    			# Find out what is on the end of the line after the
    			# conditional.
    
    			substr($s, 0, length($c), '');
    
    			$s =~ s/\n.*//g;
    
    			if ($s =~ /^\s*;/) {
    				ERROR("while should follow close brace '}'\n" . $hereprev);
    			}
    		}
    
    
    #studly caps, commented out until figure out how to distinguish between use of existing and adding new
    #		if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) {
    #		    print "No studly caps, use _\n";
    #		    print "$herecurr";
    #		    $clean = 0;
    #		}
    
    #no spaces allowed after \ in define
    
    		if ($line=~/\#\s*define.*\\\s$/) {
    
    			WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr);
    
    #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
    
    		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
    
    			my $file = "$1.h";
    			my $checkfile = "include/linux/$file";
    			if (-f "$root/$checkfile" &&
    			    $realfile ne $checkfile &&
    
    				if ($realfile =~ m{^arch/}) {
    					CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
    				} else {
    					WARN("Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
    				}
    
    # multi-statement macros should be enclosed in a do while loop, grab the
    # first statement and ensure its the whole macro if its not enclosed
    
    # in a known good container
    
    		if ($realfile !~ m@/vmlinux.lds.h$@ &&
    		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
    
    			my $ln = $linenr;
    			my $cnt = $realcnt;
    
    			my ($off, $dstat, $dcond, $rest);
    			my $ctx = '';
    
    			my $args = defined($1);
    
    			# Find the end of the macro and limit our statement
    			# search to that.
    			while ($cnt > 0 && defined $lines[$ln - 1] &&
    				$lines[$ln - 1] =~ /^(?:-|..*\\$)/)
    			{
    				$ctx .= $rawlines[$ln - 1] . "\n";
    
    				$cnt-- if ($lines[$ln - 1] !~ /^-/);
    
    				$ln++;
    			}
    			$ctx .= $rawlines[$ln - 1];
    
    			($dstat, $dcond, $ln, $cnt, $off) =
    				ctx_statement_block($linenr, $ln - $linenr + 1, 0);
    			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
    
    			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
    
    
    			# Extract the remainder of the define (if any) and
    			# rip off surrounding spaces, and trailing \'s.
    			$rest = '';
    
    			while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
    				#print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
    
    				if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
    					$rest .= substr($lines[$ln - 1], $off) . "\n";
    					$cnt--;
    				}
    
    				$ln++;
    				$off = 0;
    			}
    			$rest =~ s/\\\n.//g;
    			$rest =~ s/^\s*//s;
    			$rest =~ s/\s*$//s;
    
    			# Clean up the original statement.
    			if ($args) {
    				substr($dstat, 0, length($dcond), '');
    			} else {
    				$dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//;
    
    			$dstat =~ s/\\\n.//g;
    			$dstat =~ s/^\s*//s;
    			$dstat =~ s/\s*$//s;
    
    			# Flatten any parentheses and braces
    
    			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
    			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
    			       $dstat =~ s/\[[^\{\}]*\]/1/)
    			{
    
    			my $exceptions = qr{
    				$Declare|
    				module_param_named|
    				MODULE_PARAM_DESC|
    				DECLARE_PER_CPU|
    				DEFINE_PER_CPU|
    
    			#print "REST<$rest> dstat<$dstat>\n";
    
    			if ($rest ne '') {
    				if ($rest !~ /while\s*\(/ &&
    				    $dstat !~ /$exceptions/)
    				{
    
    					ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n");
    
    				}
    
    			} elsif ($ctx !~ /;/) {
    				if ($dstat ne '' &&
    				    $dstat !~ /^(?:$Ident|-?$Constant)$/ &&
    				    $dstat !~ /$exceptions/ &&
    
    				    $dstat =~ /$Operators/)
    				{
    
    					ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
    
    # make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
    # all assignments may have only one of the following with an assignment:
    #	.
    #	ALIGN(...)
    #	VMLINUX_SYMBOL(...)
    		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
    			WARN("vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
    		}
    
    
    # check for redundant bracing round if etc
    
    		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
    			my ($level, $endln, @chunks) =
    
    				ctx_statement_full($linenr, $realcnt, 1);
    
    			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
    
    			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
    			if ($#chunks > 0 && $level == 0) {
    
    				my $allowed = 0;
    				my $seen = 0;
    
    				my $herectx = $here . "\n";
    
    				my $ln = $linenr - 1;
    
    				for my $chunk (@chunks) {
    					my ($cond, $block) = @{$chunk};
    
    
    					# If the condition carries leading newlines, then count those as offsets.
    					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
    					my $offset = statement_rawlines($whitespace) - 1;
    
    					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
    
    					# We have looked at and allowed this specific line.
    					$suppress_ifbraces{$ln + $offset} = 1;
    
    					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
    
    					$ln += statement_rawlines($block) - 1;
    
    
    					substr($block, 0, length($cond), '');
    
    
    					$seen++ if ($block =~ /^\s*{/);
    
    
    					#print "cond<$cond> block<$block> allowed<$allowed>\n";
    					if (statement_lines($cond) > 1) {
    						#print "APW: ALLOWED: cond<$cond>\n";
    
    						$allowed = 1;
    					}
    					if ($block =~/\b(?:if|for|while)\b/) {
    
    						#print "APW: ALLOWED: block<$block>\n";
    
    					if (statement_block_size($block) > 1) {
    						#print "APW: ALLOWED: lines block<$block>\n";
    
    						$allowed = 1;
    					}
    				}
    				if ($seen && !$allowed) {
    
    					WARN("braces {} are not necessary for any arm of this statement\n" . $herectx);
    
    		if (!defined $suppress_ifbraces{$linenr - 1} &&
    
    					$line =~ /\b(if|while|for|else)\b/) {
    
    			my $allowed = 0;
    
    			# Check the pre-context.
    			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
    				#print "APW: ALLOWED: pre<$1>\n";
    				$allowed = 1;
    			}
    
    
    			my ($level, $endln, @chunks) =
    				ctx_statement_full($linenr, $realcnt, $-[0]);
    
    
    			# Check the condition.
    			my ($cond, $block) = @{$chunks[0]};
    
    			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
    
    			if (defined $cond) {
    
    				substr($block, 0, length($cond), '');
    
    			}
    			if (statement_lines($cond) > 1) {
    				#print "APW: ALLOWED: cond<$cond>\n";
    				$allowed = 1;
    			}
    			if ($block =~/\b(?:if|for|while)\b/) {
    				#print "APW: ALLOWED: block<$block>\n";
    				$allowed = 1;
    			}
    			if (statement_block_size($block) > 1) {
    				#print "APW: ALLOWED: lines block<$block>\n";
    				$allowed = 1;
    			}
    			# Check the post-context.
    			if (defined $chunks[1]) {
    				my ($cond, $block) = @{$chunks[1]};
    				if (defined $cond) {
    
    					substr($block, 0, length($cond), '');
    
    				}
    				if ($block =~ /^\s*\{/) {
    					#print "APW: ALLOWED: chunk-1 block<$block>\n";
    					$allowed = 1;
    				}
    			}
    			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
    				my $herectx = $here . "\n";;
    
    				my $cnt = statement_rawlines($block);
    
    				for (my $n = 0; $n < $cnt; $n++) {
    					$herectx .= raw_line($linenr, $n) . "\n";;
    
    
    				WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
    
    # don't include deprecated include files (uses RAW line)
    
    		for my $inc (@dep_includes) {
    
    			if ($rawline =~ m@^.\s*\#\s*include\s*\<$inc>@) {
    
    				ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr);
    
    # don't use deprecated functions
    		for my $func (@dep_functions) {
    
    			if ($line =~ /\b$func\b/) {
    
    				ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr);
    
    		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
    		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
    
    			WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
    
    # SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated
    		if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) {
    			ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr);
    		}
    
    
    # warn about #if 0
    
    		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
    
    			CHK("if this code is redundant consider removing it\n" .
    				$herecurr);
    
    # check for needless kfree() checks
    		if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
    			my $expr = $1;
    			if ($line =~ /\bkfree\(\Q$expr\E\);/) {
    
    				WARN("kfree(NULL) is safe this check is probably not required\n" . $hereprev);
    
    # check for needless usb_free_urb() checks
    		if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
    			my $expr = $1;
    			if ($line =~ /\busb_free_urb\(\Q$expr\E\);/) {
    				WARN("usb_free_urb(NULL) is safe this check is probably not required\n" . $hereprev);
    			}
    		}
    
    # warn about #ifdefs in C files
    
    #		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
    
    #			print "#ifdef in C files should be avoided\n";
    #			print "$herecurr";
    #			$clean = 0;
    #		}
    
    
    # warn about spacing in #ifdefs
    
    		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
    
    			ERROR("exactly one space required after that #$1\n" . $herecurr);
    		}
    
    
    # check for spinlock_t definitions without a comment.
    
    		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
    		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
    
    			my $which = $1;
    			if (!ctx_has_comment($first_line, $linenr)) {
    
    				CHK("$1 definition without comment\n" . $herecurr);
    
    			}
    		}
    # check for memory barriers without a comment.
    		if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
    			if (!ctx_has_comment($first_line, $linenr)) {
    
    				CHK("memory barrier without comment\n" . $herecurr);
    
    			}
    		}
    # check of hardware specific defines
    
    		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
    
    			CHK("architecture specific defines should be avoided\n" .  $herecurr);
    
    # check the location of the inline attribute, that it is between
    # storage class and type.
    
    		if ($line =~ /\b$Type\s+$Inline\b/ ||
    		    $line =~ /\b$Inline\s+$Storage\b/) {
    
    			ERROR("inline keyword should sit between storage class and type\n" . $herecurr);
    		}
    
    
    # Check for __inline__ and __inline, prefer inline
    		if ($line =~ /\b(__inline__|__inline)\b/) {
    			WARN("plain inline is preferred over $1\n" . $herecurr);
    		}
    
    
    # check for new externs in .c files.
    
    		if ($realfile =~ /\.c$/ && defined $stat &&
    
    		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
    
    			my $function_name = $1;
    			my $paren_space = $2;
    
    
    			my $s = $stat;
    			if (defined $cond) {
    				substr($s, 0, length($cond), '');
    			}
    
    			if ($s =~ /^\s*;/ &&
    			    $function_name ne 'uninitialized_var')
    			{
    
    				WARN("externs should be avoided in .c files\n" .  $herecurr);
    			}
    
    			if ($paren_space =~ /\n/) {
    				WARN("arguments for function declarations should follow identifier\n" . $herecurr);
    			}
    
    
    		} elsif ($realfile =~ /\.c$/ && defined $stat &&
    		    $stat =~ /^.\s*extern\s+/)
    		{
    			WARN("externs should be avoided in .c files\n" .  $herecurr);
    
    		}
    
    # checks for new __setup's
    		if ($rawline =~ /\b__setup\("([^"]*)"/) {
    			my $name = $1;
    
    			if (!grep(/$name/, @setup_docs)) {
    				CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
    			}
    
    
    # check for pointless casting of kmalloc return
    		if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) {
    			WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
    		}
    
    
    # check for gcc specific __FUNCTION__
    		if ($line =~ /__FUNCTION__/) {
    			WARN("__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
    		}
    
    
    # check for semaphores used as mutexes
    
    		if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) {
    
    			WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
    		}
    # check for semaphores used as mutexes
    
    		if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
    
    			WARN("consider using a completion\n" . $herecurr);
    		}
    # recommend strict_strto* over simple_strto*
    		if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
    			WARN("consider using strict_$1 in preference to simple_$1\n" . $herecurr);
    		}
    
    # check for __initcall(), use device_initcall() explicitly please
    		if ($line =~ /^.\s*__initcall\s*\(/) {
    			WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
    		}
    
    # check for struct file_operations, ensure they are const.
    
    		if ($line !~ /\bconst\b/ &&
    		    $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) {
    			WARN("struct $1 should normally be const\n" .
    				$herecurr);
    
    
    # use of NR_CPUS is usually wrong
    # ignore definitions of NR_CPUS and usage to define arrays as likely right
    		if ($line =~ /\bNR_CPUS\b/ &&
    
    		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
    		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
    
    		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
    		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
    		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
    
    		{
    			WARN("usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
    		}
    
    
    # check for %L{u,d,i} in strings
    		my $string;
    		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
    			$string = substr($rawline, $-[1], $+[1] - $-[1]);
    
    			$string =~ s/%%/__/g;
    
    			if ($string =~ /(?<!%)%L[udi]/) {
    				WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
    				last;
    			}
    		}
    
    
    # whine mightly about in_atomic
    		if ($line =~ /\bin_atomic\s*\(/) {
    			if ($realfile =~ m@^drivers/@) {
    				ERROR("do not use in_atomic in drivers\n" . $herecurr);
    
    			} elsif ($realfile !~ m@^kernel/@) {
    
    				WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
    			}
    		}
    
    	}
    
    	# If we have no input at all, then there is nothing to report on
    	# so just keep quiet.
    	if ($#rawlines == -1) {
    		exit(0);
    
    	# In mailback mode only produce a report in the negative, for
    	# things that appear to be patches.
    	if ($mailback && ($clean == 1 || !$is_patch)) {
    		exit(0);
    	}
    
    	# This is not a patch, and we are are in 'no-patch' mode so
    	# just keep quiet.
    	if (!$chk_patch && !$is_patch) {
    		exit(0);
    	}
    
    	if (!$is_patch) {
    
    		ERROR("Does not appear to be a unified-diff format patch\n");
    
    	}
    	if ($is_patch && $chk_signoff && $signoff == 0) {
    
    		ERROR("Missing Signed-off-by: line(s)\n");
    
    	print report_dump();
    
    	if ($summary && !($clean == 1 && $quiet == 1)) {
    		print "$filename " if ($summary_file);
    
    		print "total: $cnt_error errors, $cnt_warn warnings, " .
    			(($check)? "$cnt_chk checks, " : "") .
    			"$cnt_lines lines checked\n";
    		print "\n" if ($quiet == 0);
    
    	if ($clean == 1 && $quiet == 0) {
    
    		print "$vname has no obvious style problems and is ready for submission.\n"
    
    	}
    	if ($clean == 0 && $quiet == 0) {
    
    		print "$vname has style problems, please review.  If any of these errors\n";
    
    		print "are false positives report them to the maintainer, see\n";
    		print "CHECKPATCH in MAINTAINERS.\n";
    	}
    
    	return $clean;
    }