checkpatch: add --fix option for ASSIGN_IN_IF
authorJoe Perches <joe@perches.com>
Wed, 12 Aug 2020 01:35:10 +0000 (18:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Aug 2020 17:58:00 +0000 (10:58 -0700)
Add a --fix option for 2 types of single-line assignment in if statements

if ((foo = bar(...)) < BAZ) {
expands to:
foo = bar(..);
if (foo < BAZ) {
and
if ((foo = bar(...)) {
expands to:
foo = bar(...);
if (foo) {

if statements with assignments spanning multiple lines are
not converted with the --fix option.

if statements with additional logic are also not converted.

e.g.: if ((foo = bar(...)) & BAZ == BAZ) {

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Julia Lawall <julia.lawall@lip6.fr>
Link: http://lkml.kernel.org/r/9bc7c782516f37948f202deba511bc95ed279bbd.camel@perches.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
scripts/checkpatch.pl

index ba9ab2b..5cb791e 100755 (executable)
@@ -5020,8 +5020,30 @@ sub process {
                        my ($s, $c) = ($stat, $cond);
 
                        if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
-                               ERROR("ASSIGN_IN_IF",
-                                     "do not use assignment in if condition\n" . $herecurr);
+                               if (ERROR("ASSIGN_IN_IF",
+                                         "do not use assignment in if condition\n" . $herecurr) &&
+                                   $fix && $perl_version_ok) {
+                                       if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
+                                               my $space = $1;
+                                               my $not = $2;
+                                               my $statement = $3;
+                                               my $assigned = $4;
+                                               my $test = $8;
+                                               my $against = $9;
+                                               my $brace = $15;
+                                               fix_delete_line($fixlinenr, $rawline);
+                                               fix_insert_line($fixlinenr, "$space$statement;");
+                                               my $newline = "${space}if (";
+                                               $newline .= '!' if defined($not);
+                                               $newline .= '(' if (defined $not && defined($test) && defined($against));
+                                               $newline .= "$assigned";
+                                               $newline .= " $test $against" if (defined($test) && defined($against));
+                                               $newline .= ')' if (defined $not && defined($test) && defined($against));
+                                               $newline .= ')';
+                                               $newline .= " {" if (defined($brace));
+                                               fix_insert_line($fixlinenr + 1, $newline);
+                                       }
+                               }
                        }
 
                        # Find out what is on the end of the line after the