checkpatch: add ability to --fix (coalesce) string fragments on multiple lines

Add --fix option to coalesce string fragments.

This does not coalesce string fragments that have newline terminations or
are otherwise exempted.

Other miscellanea:

o move all the string tests together.
o fix get_quoted_string function for tab characters
o fix concatination typo

Signed-off-by: Joe Perches <joe@perches.com>
Cc: Andy Whitcroft <apw@canonical.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Joe Perches 2014-12-10 15:52:05 -08:00 committed by Linus Torvalds
parent b75ac618df
commit 5e4f6ba5eb
1 changed files with 69 additions and 46 deletions

View File

@ -946,7 +946,7 @@ sub sanitise_line {
sub get_quoted_string {
my ($line, $rawline) = @_;
return "" if ($line !~ m/(\"[X]+\")/g);
return "" if ($line !~ m/(\"[X\t]+\")/g);
return substr($rawline, $-[0], $+[0] - $-[0]);
}
@ -1847,6 +1847,7 @@ sub process {
my $non_utf8_charset = 0;
my $last_blank_line = 0;
my $last_coalesced_string_linenr = -1;
our @report = ();
our $cnt_lines = 0;
@ -2413,33 +2414,6 @@ sub process {
"line over $max_line_length characters\n" . $herecurr);
}
# Check for user-visible strings broken across lines, which breaks the ability
# to grep for the string. Make exceptions when the previous string ends in a
# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
if ($line =~ /^\+\s*"/ &&
$prevline =~ /"\s*$/ &&
$prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
WARN("SPLIT_STRING",
"quoted string split across lines\n" . $hereprev);
}
# check for missing a space in a string concatination
if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
WARN('MISSING_SPACE',
"break quoted strings at a space character\n" . $hereprev);
}
# check for spaces before a quoted newline
if ($rawline =~ /^.*\".*\s\\n/) {
if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
"unnecessary whitespace before a quoted newline\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
}
}
# check for adding lines without a newline.
if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
WARN("MISSING_EOF_NEWLINE",
@ -4458,6 +4432,55 @@ sub process {
"Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
}
# Check for user-visible strings broken across lines, which breaks the ability
# to grep for the string. Make exceptions when the previous string ends in a
# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
if ($line =~ /^\+\s*"[X\t]*"/ &&
$prevline =~ /"\s*$/ &&
$prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
if (WARN("SPLIT_STRING",
"quoted string split across lines\n" . $hereprev) &&
$fix &&
$prevrawline =~ /^\+.*"\s*$/ &&
$last_coalesced_string_linenr != $linenr - 1) {
my $extracted_string = get_quoted_string($line, $rawline);
my $comma_close = "";
if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
$comma_close = $1;
}
fix_delete_line($fixlinenr - 1, $prevrawline);
fix_delete_line($fixlinenr, $rawline);
my $fixedline = $prevrawline;
$fixedline =~ s/"\s*$//;
$fixedline .= substr($extracted_string, 1) . trim($comma_close);
fix_insert_line($fixlinenr - 1, $fixedline);
$fixedline = $rawline;
$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
if ($fixedline !~ /\+\s*$/) {
fix_insert_line($fixlinenr, $fixedline);
}
$last_coalesced_string_linenr = $linenr;
}
}
# check for missing a space in a string concatenation
if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
WARN('MISSING_SPACE',
"break quoted strings at a space character\n" . $hereprev);
}
# check for spaces before a quoted newline
if ($rawline =~ /^.*\".*\s\\n/) {
if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
"unnecessary whitespace before a quoted newline\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
}
}
# concatenated string without spaces between elements
if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {
CHK("CONCATENATED_STRING",
@ -4470,6 +4493,24 @@ sub process {
"Consecutive strings are generally better as a single string\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);
last;
}
}
# 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);
}
# warn about #if 0
if ($line =~ /^.\s*\#\s*if\s+0\b/) {
CHK("REDUNDANT_CODE",
@ -4754,12 +4795,6 @@ sub process {
}
}
# 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",
@ -5169,18 +5204,6 @@ sub process {
"#define of '$1' is wrong - use Kconfig variables or standard guards instead\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);
last;
}
}
# whine mightly about in_atomic
if ($line =~ /\bin_atomic\s*\(/) {
if ($realfile =~ m@^drivers/@) {