Newer
Older
"extern prototypes should be avoided in .h files\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
# 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);
}
# check for function declarations that have arguments without identifier names
if (defined $stat &&
$stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
$1 ne "void") {
my $args = trim($1);
while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
my $arg = trim($1);
if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
WARN("FUNCTION_ARGUMENTS",
"function definition argument '$arg' should also have an identifier name\n" . $herecurr);
}
}
}
# check for function definitions
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
$context_function = $1;
# check for multiline function definition with misplaced open brace
my $ok = 0;
my $cnt = statement_rawlines($stat);
my $herectx = $here . "\n";
for (my $n = 0; $n < $cnt; $n++) {
my $rl = raw_line($linenr, $n);
$herectx .= $rl . "\n";
$ok = 1 if ($rl =~ /^[ \+]\{/);
$ok = 1 if ($rl =~ /\{/ && $n == 0);
last if $rl =~ /^[ \+].*\{/;
}
if (!$ok) {
ERROR("OPEN_BRACE",
"open brace '{' following function definitions go on the next line\n" . $herectx);
}
}
# 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/admin-guide/kernel-parameters.rst\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);
}
# alloc style
# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
if ($^V && $^V ge 5.10.0 &&
$line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
CHK("ALLOC_SIZEOF_STRUCT",
"Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
}
# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
my $oldfunc = $3;
my $a1 = $4;
my $a2 = $10;
my $newfunc = "kmalloc_array";
$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
my $r1 = $a1;
my $r2 = $a2;
if ($a1 =~ /^sizeof\s*\S/) {
$r1 = $a2;
$r2 = $a1;
}
if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
!($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
my $cnt = statement_rawlines($stat);
my $herectx = get_stat_here($linenr, $cnt, $here);
if (WARN("ALLOC_WITH_MULTIPLY",
"Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
$cnt == 1 &&
$fix) {
$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
}
}
}
# check for krealloc arg reuse
if ($^V && $^V ge 5.10.0 &&
$line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
WARN("KREALLOC_ARG_REUSE",
"Reusing the krealloc arg is almost always a bug\n" . $herecurr);
}
# check for alloc argument mismatch
if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
WARN("ALLOC_ARRAY_ARGS",
"$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
}
# check for multiple semicolons
if ($line =~ /;\s*;\s*$/) {
if (WARN("ONE_SEMICOLON",
"Statements terminations use 1 semicolon\n" . $herecurr) &&
$fix) {
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
}
}
# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
if ($realfile !~ m@^include/uapi/@ &&
$line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
my $ull = "";
$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
if (CHK("BIT_MACRO",
"Prefer using the BIT$ull macro\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
}
}
# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
my $config = $1;
if (WARN("PREFER_IS_ENABLED",
"Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
# check for case / default statements not preceded by break/fallthrough/switch
if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
my $has_break = 0;
my $has_statement = 0;
my $count = 0;
my $prevline = $linenr;
while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
$prevline--;
my $rline = $rawlines[$prevline - 1];
my $fline = $lines[$prevline - 1];
last if ($fline =~ /^\@\@/);
next if ($fline =~ /^\-/);
next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
next if ($fline =~ /^.[\s$;]*$/);
$has_statement = 1;
$count++;
$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
}
if (!$has_break && $has_statement) {
WARN("MISSING_BREAK",
"Possible switch case/default not preceded by break or fallthrough comment\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 $cnt = statement_rawlines($stat);
my $herectx = get_stat_here($linenr, $cnt, $here);
WARN("DEFAULT_NO_BREAK",
"switch default: should use break\n" . $herectx);
}
# check for gcc specific __FUNCTION__
if ($line =~ /\b__FUNCTION__\b/) {
if (WARN("USE_FUNC",
"__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
# check for uses of __DATE__, __TIME__, __TIMESTAMP__
while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
ERROR("DATE_TIME",
"Use of the '$1' macro makes the build non-deterministic\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);
}
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
# check for comparisons against true and false
if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
my $lead = $1;
my $arg = $2;
my $test = $3;
my $otype = $4;
my $trail = $5;
my $op = "!";
($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
my $type = lc($otype);
if ($type =~ /^(?:true|false)$/) {
if (("$test" eq "==" && "$type" eq "true") ||
("$test" eq "!=" && "$type" eq "false")) {
$op = "";
}
CHK("BOOL_COMPARISON",
"Using comparison to $otype is error prone\n" . $herecurr);
## maybe suggesting a correct construct would better
## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\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 or more appropriate function please
if ($line =~ /^.\s*__initcall\s*\(/) {
WARN("USE_DEVICE_INITCALL",
"please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
}
# check for various structs that are normally const (ops, kgdb, device_tree)
# and avoid what seem like struct definitions 'struct foo {'
if ($line !~ /\bconst\b/ &&
$line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
"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("NR_CPUS",
"usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
}
# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
ERROR("DEFINE_ARCH_HAS",
"#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
}
# likely/unlikely comparisons similar to "(likely(foo) > 0)"
if ($^V && $^V ge 5.10.0 &&
$line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
WARN("LIKELY_MISUSE",
"Using $1 should generally have parentheses around the comparison\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 mutex_trylock_recursive usage
if ($line =~ /mutex_trylock_recursive/) {
ERROR("LOCKING",
"recursive locking is bad, do not use this ever.\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_\w+.*\b$mode_perms_world_writable\b/ ||
$line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
WARN("EXPORTED_WORLD_WRITABLE",
"Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
}
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
# and whether or not function naming is typical and if
# DEVICE_ATTR permissions uses are unusual too
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
my $var = $1;
my $perms = $2;
my $show = $3;
my $store = $4;
my $octal_perms = perms_to_octal($perms);
if ($show =~ /^${var}_show$/ &&
$store =~ /^${var}_store$/ &&
$octal_perms eq "0644") {
if (WARN("DEVICE_ATTR_RW",
"Use DEVICE_ATTR_RW\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
}
} elsif ($show =~ /^${var}_show$/ &&
$store =~ /^NULL$/ &&
$octal_perms eq "0444") {
if (WARN("DEVICE_ATTR_RO",
"Use DEVICE_ATTR_RO\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
}
} elsif ($show =~ /^NULL$/ &&
$store =~ /^${var}_store$/ &&
$octal_perms eq "0200") {
if (WARN("DEVICE_ATTR_WO",
"Use DEVICE_ATTR_WO\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
}
} elsif ($octal_perms eq "0644" ||
$octal_perms eq "0444" ||
$octal_perms eq "0200") {
my $newshow = "$show";
$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
my $newstore = $store;
$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
my $rename = "";
if ($show ne $newshow) {
$rename .= " '$show' to '$newshow'";
}
if ($store ne $newstore) {
$rename .= " '$store' to '$newstore'";
}
WARN("DEVICE_ATTR_FUNCTIONS",
"Consider renaming function(s)$rename\n" . $herecurr);
} else {
WARN("DEVICE_ATTR_PERMS",
"DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
}
}
# Mode permission misuses where it seems decimal should be octal
# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
# specific definition of not visible in sysfs.
# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
# use the default permissions
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$line =~ /$mode_perms_search/) {
foreach my $entry (@mode_permission_funcs) {
my $func = $entry->[0];
my $arg_pos = $entry->[1];
my $lc = $stat =~ tr@\n@@;
$lc = $lc + $linenr;
my $stat_real = get_stat_real($linenr, $lc);
my $skip_args = "";
if ($arg_pos > 1) {
$arg_pos--;
$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
}
my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
if ($stat =~ /$test/) {
my $val = $1;
$val = $6 if ($skip_args ne "");
if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
(($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
($val =~ /^$Octal$/ && length($val) ne 4))) {
ERROR("NON_OCTAL_PERMISSIONS",
"Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
}
if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
ERROR("EXPORTED_WORLD_WRITABLE",
"Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
}
}
}
}
# check for uses of S_<PERMS> that could be octal for readability
while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
my $oval = $1;
my $octal = perms_to_octal($oval);
if (WARN("SYMBOLIC_PERMS",
"Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
}
}
# validate content of MODULE_LICENSE against list from include/linux/module.h
if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
my $extracted_string = get_quoted_string($line, $rawline);
my $valid_licenses = qr{
GPL|
GPL\ v2|
GPL\ and\ additional\ rights|
Dual\ BSD/GPL|
Dual\ MIT/GPL|
Dual\ MPL/GPL|
Proprietary
}x;
if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
WARN("MODULE_LICENSE",
"unknown module license " . $extracted_string . "\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 && $filename !~ /cover-letter\.patch$/) {
ERROR("NOT_UNIFIED_DIFF",
"Does not appear to be a unified-diff format patch\n");
}
if ($is_patch && $has_commit_log && $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";
}
if ($quiet == 0) {
# If there were any defects found and not already fixing them
if (!$clean and !$fix) {
print << "EOM"
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
EOM
# If there were whitespace errors which cleanpatch can fix
# then suggest that.
if ($rpt_cleaners) {
$rpt_cleaners = 0;
print << "EOM"
NOTE: Whitespace errors detected.
You may wish to use scripts/cleanpatch or scripts/cleanfile
EOM
if ($clean == 0 && $fix &&
("@rawlines" ne "@fixed" ||
$#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
my $newfile = $filename;
$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
my $linecount = 0;
my $f;
@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
open($f, '>', $newfile)
or die "$P: Can't open $newfile for write\n";
foreach my $fixed_line (@fixed) {
$linecount++;
if ($file) {
if ($linecount > 3) {
$fixed_line =~ s/^\+//;
print $f $fixed_line . "\n";
}
} else {
print $f $fixed_line . "\n";
}
}
close($f);
if (!$quiet) {
print << "EOM";
Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
Do _NOT_ trust the results written to this file.
Do _NOT_ submit these changes without inspecting them for correctness.
This EXPERIMENTAL file is simply a convenience to help rewrite patches.
No warranties, expressed or implied...
EOM
}
if ($quiet == 0) {
print "\n";
if ($clean == 1) {
print "$vname has no obvious style problems and is ready for submission.\n";
} else {
print "$vname has style problems, please review.\n";
}
}
return $clean;
}