Skip to content

Commit

Permalink
checkpatch: add ability to insert and delete lines to patch/file
Browse files Browse the repository at this point in the history
This can be valuable to insert or delete blank lines as well as fix
misplaced brace or else uses.

Store indexes of lines to be added/deleted and the new lines.

When creating the --fix file, insert or delete the appropriate lines and
update the patch range information.

Signed-off-by: Joe Perches <[email protected]>
Cc: Andy Whitcroft <[email protected]>
Cc: Dan Carpenter <[email protected]>
Cc: Josh Triplett <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
JoePerches authored and torvalds committed Aug 7, 2014
1 parent 194f66f commit d752fcc
Showing 1 changed file with 130 additions and 11 deletions.
141 changes: 130 additions & 11 deletions scripts/checkpatch.pl
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ sub git_commit_info {
my @rawlines = ();
my @lines = ();
my @fixed = ();
my @fixed_inserted = ();
my @fixed_deleted = ();
my $fixlinenr = -1;

my $vname;
Expand Down Expand Up @@ -613,6 +615,8 @@ sub git_commit_info {
@rawlines = ();
@lines = ();
@fixed = ();
@fixed_inserted = ();
@fixed_deleted = ();
$fixlinenr = -1;
}

Expand Down Expand Up @@ -1526,6 +1530,69 @@ sub report_dump {
our @report;
}

sub fixup_current_range {
my ($lineRef, $offset, $length) = @_;

if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
my $o = $1;
my $l = $2;
my $no = $o + $offset;
my $nl = $l + $length;
$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
}
}

sub fix_inserted_deleted_lines {
my ($linesRef, $insertedRef, $deletedRef) = @_;

my $range_last_linenr = 0;
my $delta_offset = 0;

my $old_linenr = 0;
my $new_linenr = 0;

my $next_insert = 0;
my $next_delete = 0;

my @lines = ();

my $inserted = @{$insertedRef}[$next_insert++];
my $deleted = @{$deletedRef}[$next_delete++];

foreach my $old_line (@{$linesRef}) {
my $save_line = 1;
my $line = $old_line; #don't modify the array
if ($line =~ /^(?:\+\+\+\|\-\-\-)\s+\S+/) { #new filename
$delta_offset = 0;
} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
$range_last_linenr = $new_linenr;
fixup_current_range(\$line, $delta_offset, 0);
}

while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
$deleted = @{$deletedRef}[$next_delete++];
$save_line = 0;
fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
}

while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
push(@lines, ${$inserted}{'LINE'});
$inserted = @{$insertedRef}[$next_insert++];
$new_linenr++;
fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
}

if ($save_line) {
push(@lines, $line);
$new_linenr++;
}

$old_linenr++;
}

return @lines;
}

sub ERROR {
my ($type, $msg) = @_;

Expand Down Expand Up @@ -2377,16 +2444,31 @@ sub process {
$line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
$line =~ /^\+\s*DECLARE/ ||
$line =~ /^\+\s*__setup/)) {
CHK("LINE_SPACING",
"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev);
if (CHK("LINE_SPACING",
"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
$fix) {
my $inserted = {
LINENR => $fixlinenr,
LINE => "\+",
};
push(@fixed_inserted, $inserted);
}
}

# check for multiple consecutive blank lines
if ($prevline =~ /^[\+ ]\s*$/ &&
$line =~ /^\+\s*$/ &&
$last_blank_line != ($linenr - 1)) {
CHK("LINE_SPACING",
"Please don't use multiple blank lines\n" . $hereprev);
if (CHK("LINE_SPACING",
"Please don't use multiple blank lines\n" . $hereprev) &&
$fix) {
my $deleted = {
LINENR => $fixlinenr,
LINE => $rawline,
};
push(@fixed_deleted, $deleted);
}

$last_blank_line = $linenr;
}

Expand Down Expand Up @@ -2424,8 +2506,15 @@ sub process {
$sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
# indentation of previous and current line are the same
(($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
WARN("LINE_SPACING",
"Missing a blank line after declarations\n" . $hereprev);
if (WARN("LINE_SPACING",
"Missing a blank line after declarations\n" . $hereprev) &&
$fix) {
my $inserted = {
LINENR => $fixlinenr,
LINE => "\+",
};
push(@fixed_inserted, $inserted);
}
}

# check for spaces at the beginning of a line.
Expand Down Expand Up @@ -2627,7 +2716,7 @@ sub process {
#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";

if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
ERROR("OPEN_BRACE",
"that open brace { should be on the previous line\n" .
"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
Expand Down Expand Up @@ -2777,8 +2866,34 @@ sub process {
# check for initialisation to aggregates open brace on the next line
if ($line =~ /^.\s*{/ &&
$prevline =~ /(?:^|[^=])=\s*$/) {
ERROR("OPEN_BRACE",
"that open brace { should be on the previous line\n" . $hereprev);
if (ERROR("OPEN_BRACE",
"that open brace { should be on the previous line\n" . $hereprev) &&
$fix && $prevline =~ /^\+/) {
my $deleted = {
LINENR => $fixlinenr - 1,
LINE => $prevrawline,
};
push(@fixed_deleted, $deleted);
$deleted = {
LINENR => $fixlinenr,
LINE => $rawline,
};
push(@fixed_deleted, $deleted);
my $fixedline = $prevrawline;
$fixedline =~ s/\s*=\s*$/ = {/;
my $inserted = {
LINENR => $fixlinenr,
LINE => $fixedline,
};
push(@fixed_inserted, $inserted);
$fixedline = $line;
$fixedline =~ s/^(.\s*){\s*/$1/;
$inserted = {
LINENR => $fixlinenr,
LINE => $fixedline,
};
push(@fixed_inserted, $inserted);
}
}

#
Expand Down Expand Up @@ -4900,20 +5015,24 @@ sub process {
hash_show_words(\%use_type, "Used");
hash_show_words(\%ignore_type, "Ignored");

if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
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";
print $f $fixed_line . "\n";
}
} else {
print $f $fixed_line . "\n";
Expand Down

0 comments on commit d752fcc

Please sign in to comment.