Skip to content
Snippets Groups Projects
checkpatch.pl 99.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • 			    $dstat !~ /$exceptions/ &&
    			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
    
    			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
    
    			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
    			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
    			    $dstat !~ /^do\s*{/ &&					# do {...
    			    $dstat !~ /^\({/)						# ({...
    			{
    				$ctx =~ s/\n*$//;
    				my $herectx = $here . "\n";
    				my $cnt = statement_rawlines($ctx);
    
    				for (my $n = 0; $n < $cnt; $n++) {
    					$herectx .= raw_line($linenr, $n) . "\n";
    
    				if ($dstat =~ /;/) {
    					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
    					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
    				} else {
    
    					ERROR("COMPLEX_MACRO",
    
    					      "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
    
    # check for line continuations outside of #defines, preprocessor #, and asm
    
    
    		} else {
    			if ($prevline !~ /^..*\\$/ &&
    
    			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
    			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
    
    			    $line =~ /^\+.*\\$/) {
    				WARN("LINE_CONTINUATIONS",
    				     "Avoid unnecessary line continuations\n" . $herecurr);
    			}
    
    # do {} while (0) macro tests:
    # single-statement macros do not need to be enclosed in do while (0) loop,
    # macro should not end with a semicolon
    		if ($^V && $^V ge 5.10.0 &&
    		    $realfile !~ m@/vmlinux.lds.h$@ &&
    		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
    			my $ln = $linenr;
    			my $cnt = $realcnt;
    			my ($off, $dstat, $dcond, $rest);
    			my $ctx = '';
    			($dstat, $dcond, $ln, $cnt, $off) =
    				ctx_statement_block($linenr, $realcnt, 0);
    			$ctx = $dstat;
    
    			$dstat =~ s/\\\n.//g;
    
    			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
    				my $stmts = $2;
    				my $semis = $3;
    
    				$ctx =~ s/\n*$//;
    				my $cnt = statement_rawlines($ctx);
    				my $herectx = $here . "\n";
    
    				for (my $n = 0; $n < $cnt; $n++) {
    					$herectx .= raw_line($linenr, $n) . "\n";
    				}
    
    
    				if (($stmts =~ tr/;/;/) == 1 &&
    				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
    
    					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
    					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
    				}
    				if (defined $semis && $semis ne "") {
    					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
    					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
    				}
    			}
    		}
    
    
    # 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("MISSING_VMLINUX_SYMBOL",
    			     "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 = ();
    				my $allow = 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[$allow]>\n";
    
    					if (statement_lines($cond) > 1) {
    						#print "APW: ALLOWED: cond<$cond>\n";
    
    					}
    					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";
    
    				if ($seen) {
    					my $sum_allowed = 0;
    					foreach (@allowed) {
    						$sum_allowed += $_;
    					}
    					if ($sum_allowed == 0) {
    						WARN("BRACES",
    						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
    					} elsif ($sum_allowed != $allow &&
    						 $seen != $allow) {
    						CHK("BRACES",
    						    "braces {} should be used on all arms 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 $cnt = statement_rawlines($block);
    
    				for (my $n = 0; $n < $cnt; $n++) {
    
    					$herectx .= raw_line($linenr, $n) . "\n";
    
    				WARN("BRACES",
    				     "braces {} are not necessary for single statement blocks\n" . $herectx);
    
    # check for unnecessary blank lines around braces
    		if (($line =~ /^..*}\s*$/ && $prevline =~ /^.\s*$/)) {
    			CHK("BRACES",
    			    "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
    		}
    		if (($line =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
    			CHK("BRACES",
    			    "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
    		}
    
    
    # no volatiles please
    
    		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
    		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
    
    			WARN("VOLATILE",
    			     "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
    
    # warn about #if 0
    
    		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
    
    			CHK("REDUNDANT_CODE",
    			    "if this code is redundant consider removing it\n" .
    
    # check for needless "if (<foo>) fn(<foo>)" uses
    		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
    			my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
    			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
    				WARN('NEEDLESS_IF',
    				     "$1(NULL) is safe this check is probably not required\n" . $hereprev);
    
    # prefer usleep_range over udelay
    		if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) {
    			# ignore udelay's < 10, however
    			if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) {
    
    				CHK("USLEEP_RANGE",
    				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
    
    # warn about unexpectedly long msleep's
    		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
    			if ($1 < 20) {
    
    				WARN("MSLEEP",
    				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
    
    # 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("SPACING",
    			      "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("UNCOMMENTED_DEFINITION",
    				    "$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",
    				    "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("ARCH_DEFINES",
    			    "architecture specific defines should be avoided\n" .  $herecurr);
    
    # Check that the storage class is at the beginning of a declaration
    		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
    
    			WARN("STORAGE_CLASS",
    			     "storage class should be at the beginning of the declaration\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_LOCATION",
    			      "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("INLINE",
    			     "plain inline is preferred over $1\n" . $herecurr);
    
    # Check for __attribute__ packed, prefer __packed
    		if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
    
    			WARN("PREFER_PACKED",
    			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
    
    # Check for __attribute__ aligned, prefer __aligned
    		if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
    
    			WARN("PREFER_ALIGNED",
    			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
    
    # Check for __attribute__ format(printf, prefer __printf
    		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
    			WARN("PREFER_PRINTF",
    			     "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
    		}
    
    
    # Check for __attribute__ format(scanf, prefer __scanf
    		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
    			WARN("PREFER_SCANF",
    			     "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
    		}
    
    
    # check for sizeof(&)
    		if ($line =~ /\bsizeof\s*\(\s*\&/) {
    
    			WARN("SIZEOF_ADDRESS",
    			     "sizeof(& should be avoided\n" . $herecurr);
    
    # check for sizeof without parenthesis
    		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
    			WARN("SIZEOF_PARENTHESIS",
    			     "sizeof $1 should be sizeof($1)\n" . $herecurr);
    		}
    
    
    # check for line continuations in quoted strings with odd counts of "
    		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
    
    			WARN("LINE_CONTINUATIONS",
    			     "Avoid line continuations in quoted strings\n" . $herecurr);
    
    # check for struct spinlock declarations
    		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
    			WARN("USE_SPINLOCK_T",
    			     "struct spinlock should be spinlock_t\n" . $herecurr);
    		}
    
    
    		if ($^V && $^V ge 5.10.0 &&
    		    defined $stat &&
    
    		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
    
    			my $ms_addr = $2;
    
    			my $ms_val = $7;
    			my $ms_size = $12;
    
    
    			if ($ms_size =~ /^(0x|)0$/i) {
    				ERROR("MEMSET",
    
    				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
    
    			} elsif ($ms_size =~ /^(0x|)1$/i) {
    				WARN("MEMSET",
    
    				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
    			}
    		}
    
    # typecasts on min/max could be min_t/max_t
    
    		if ($^V && $^V ge 5.10.0 &&
    		    defined $stat &&
    
    		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
    
    			if (defined $2 || defined $7) {
    
    				my $call = $1;
    				my $cast1 = deparenthesize($2);
    				my $arg1 = $3;
    
    				my $cast2 = deparenthesize($7);
    				my $arg2 = $8;
    
    				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
    
    					$cast = "$cast1 or $cast2";
    				} elsif ($cast1 ne "") {
    					$cast = $cast1;
    				} else {
    					$cast = $cast2;
    				}
    				WARN("MINMAX",
    				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
    
    # check usleep_range arguments
    		if ($^V && $^V ge 5.10.0 &&
    		    defined $stat &&
    		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
    			my $min = $1;
    			my $max = $7;
    			if ($min eq $max) {
    				WARN("USLEEP_RANGE",
    				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
    			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
    				 $min > $max) {
    				WARN("USLEEP_RANGE",
    				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
    			}
    		}
    
    
    # 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("AVOID_EXTERNS",
    				     "externs should be avoided in .c files\n" .  $herecurr);
    
    			}
    
    			if ($paren_space =~ /\n/) {
    
    				WARN("FUNCTION_ARGUMENTS",
    				     "arguments for function declarations should follow identifier\n" . $herecurr);
    
    
    		} elsif ($realfile =~ /\.c$/ && defined $stat &&
    		    $stat =~ /^.\s*extern\s+/)
    		{
    
    			WARN("AVOID_EXTERNS",
    			     "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("UNDOCUMENTED_SETUP",
    				    "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
    
    
    # check for pointless casting of kmalloc return
    
    		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
    
    			WARN("UNNECESSARY_CASTS",
    			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
    
    # check for multiple semicolons
    		if ($line =~ /;\s*;\s*$/) {
    
    			WARN("ONE_SEMICOLON",
    			     "Statements terminations use 1 semicolon\n" . $herecurr);
    		}
    
    # check for switch/default statements without a break;
    		if ($^V && $^V ge 5.10.0 &&
    		    defined $stat &&
    		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
    			my $ctx = '';
    			my $herectx = $here . "\n";
    			my $cnt = statement_rawlines($stat);
    			for (my $n = 0; $n < $cnt; $n++) {
    				$herectx .= raw_line($linenr, $n) . "\n";
    			}
    			WARN("DEFAULT_NO_BREAK",
    			     "switch default: should use break\n" . $herectx);
    
    # check for gcc specific __FUNCTION__
    		if ($line =~ /__FUNCTION__/) {
    
    			WARN("USE_FUNC",
    			     "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
    
    # check for use of yield()
    		if ($line =~ /\byield\s*\(\s*\)/) {
    			WARN("YIELD",
    			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
    		}
    
    
    # check for semaphores initialized locked
    		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
    
    			WARN("CONSIDER_COMPLETION",
    			     "consider using a completion\n" . $herecurr);
    
    # recommend kstrto* over simple_strto* and strict_strto*
    		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
    
    			WARN("CONSIDER_KSTRTO",
    
    			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
    
    # check for __initcall(), use device_initcall() explicitly please
    		if ($line =~ /^.\s*__initcall\s*\(/) {
    
    			WARN("USE_DEVICE_INITCALL",
    			     "please use device_initcall() instead of __initcall()\n" . $herecurr);
    
    # check for various ops structs, ensure they are const.
    		my $struct_ops = qr{acpi_dock_ops|
    				address_space_operations|
    				backlight_ops|
    				block_device_operations|
    				dentry_operations|
    				dev_pm_ops|
    				dma_map_ops|
    				extent_io_ops|
    				file_lock_operations|
    				file_operations|
    				hv_ops|
    				ide_dma_ops|
    				intel_dvo_dev_ops|
    				item_operations|
    				iwl_ops|
    				kgdb_arch|
    				kgdb_io|
    				kset_uevent_ops|
    				lock_manager_operations|
    				microcode_ops|
    				mtrr_ops|
    				neigh_ops|
    				nlmsvc_binding|
    				pci_raw_ops|
    				pipe_buf_operations|
    				platform_hibernation_ops|
    				platform_suspend_ops|
    				proto_ops|
    				rpc_pipe_ops|
    				seq_operations|
    				snd_ac97_build_ops|
    				soc_pcmcia_socket_ops|
    				stacktrace_ops|
    				sysfs_ops|
    				tty_operations|
    				usb_mon_operations|
    				wd_ops}x;
    
    		if ($line !~ /\bconst\b/ &&
    
    		    $line =~ /\bstruct\s+($struct_ops)\b/) {
    
    			WARN("CONST_STRUCT",
    			     "struct $1 should normally be const\n" .
    
    
    # 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("NR_CPUS",
    			     "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("PRINTF_L",
    				     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
    
    
    # whine mightly about in_atomic
    		if ($line =~ /\bin_atomic\s*\(/) {
    			if ($realfile =~ m@^drivers/@) {
    
    				ERROR("IN_ATOMIC",
    				      "do not use in_atomic in drivers\n" . $herecurr);
    
    			} elsif ($realfile !~ m@^kernel/@) {
    
    				WARN("IN_ATOMIC",
    				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
    
    
    # check for lockdep_set_novalidate_class
    		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
    		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
    			if ($realfile !~ m@^kernel/lockdep@ &&
    			    $realfile !~ m@^include/linux/lockdep@ &&
    			    $realfile !~ m@^drivers/base/core@) {
    
    				ERROR("LOCKDEP",
    				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
    
    
    		if ($line =~ /debugfs_create_file.*S_IWUGO/ ||
    		    $line =~ /DEVICE_ATTR.*S_IWUGO/ ) {
    
    			WARN("EXPORTED_WORLD_WRITABLE",
    			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\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("NOT_UNIFIED_DIFF",
    		      "Does not appear to be a unified-diff format patch\n");
    
    	}
    	if ($is_patch && $chk_signoff && $signoff == 0) {
    
    		ERROR("MISSING_SIGN_OFF",
    		      "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 ($^V lt 5.10.0) {
    			print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
    			print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
    		}
    
    
    		# If there were whitespace errors which cleanpatch can fix
    		# then suggest that.
    		if ($rpt_cleaners) {
    			print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
    			print "      scripts/cleanfile\n\n";
    
    	if ($quiet == 0 && keys %ignore_type) {
    
    	    print "NOTE: Ignored message types:";
    	    foreach my $ignore (sort keys %ignore_type) {
    		print " $ignore";
    	    }
    
    	if ($clean == 1 && $quiet == 0) {
    
    		print "$vname has no obvious style problems and is ready for submission.\n"
    
    	}
    	if ($clean == 0 && $quiet == 0) {
    
    		print << "EOM";
    $vname has style problems, please review.
    
    If any of these errors are false positives, please report
    them to the maintainer, see CHECKPATCH in MAINTAINERS.
    EOM
    
    	return $clean;
    }