From: Steve Hancock Date: Tue, 23 Jun 2020 00:15:24 +0000 (-0700) Subject: improved error ouput for --assert-tidy X-Git-Tag: 20200619.02~18 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=0395c5ad9e9aca8988a2448afd6b146864a6cf99;p=perltidy.git improved error ouput for --assert-tidy --- diff --git a/lib/Perl/Tidy.pm b/lib/Perl/Tidy.pm index 51a04b46..c788488f 100644 --- a/lib/Perl/Tidy.pm +++ b/lib/Perl/Tidy.pm @@ -1707,6 +1707,37 @@ EOM return 1; } # end of main program perltidy +sub line_diff { + + # Given two strings, return + # $diff_marker = a string with carat (^) symbols indicating differences + # $pos1 = character position of first difference; pos1=-1 if no difference + + # Form exclusive or of the strings, which has null characters where strings + # have same common characters so non-null characters indicate character + # differences. + my ( $s1, $s2 ) = @_; + my $mask = $s1 ^ $s2; + my $diff_marker = ""; + my $pos = -1; + my $pos1 = $pos; + my $count = 0; + my $len1 = length($s1); + my $len2 = length($s2); + + while ( $mask =~ /[^\0]/g ) { + $count++; + my $pos_last = $pos; + $pos = $-[0]; + if ( $count == 1 ) { $pos1 = $pos; } + $diff_marker .= ' ' x ( $pos - $pos_last - 1 ) . '^'; + + # we could continue to mark all differences, but there is no point + last; + } + return wantarray ? ( $diff_marker, $pos1 ) : $diff_marker; +} + sub compare_string_buffers { # Compare input and output string buffers and return a brief text @@ -1725,6 +1756,13 @@ sub compare_string_buffers { my ( $linei, $lineo ); my ( $counti, $counto ) = ( 0, 0 ); my ( $last_nonblank_line, $last_nonblank_count ) = ( "", 0 ); + my $truncate = sub { + my ( $str, $lenmax ) = @_; + if ( length($str) > $lenmax ) { + $str = substr( $str, 0, $lenmax ) . "..."; + } + return $str; + }; while (1) { if ($linei) { $last_nonblank_line = $linei; @@ -1734,36 +1772,64 @@ sub compare_string_buffers { $lineo = $fho->getline(); # compare chomp'ed lines - if ( defined($linei) ) { $counti++; chomp $linei } if ( defined($lineo) ) { $counto++; chomp $lineo } # see if one or both ended before a difference last unless ( defined($linei) && defined($lineo) ); - if ( $linei ne $lineo ) { + next if ( $linei eq $lineo ); - my ( $trimi, $trimo ) = ( $linei, $lineo ); - $trimi =~ s/\s+$//; - $trimo =~ s/\s+$//; - my $reason = - ( $trimi eq $trimo ) ? " (trailing whitespace difference)" : ""; + # lines differ ... + my ( $line_diff, $pos1 ) = line_diff( $linei, $lineo ); + my $reason = "Files first differ at character $pos1 of line $counti"; + + my ( $leading_ws_i, $leading_ws_o ) = ( "", "" ); + if ( $linei =~ /^(\s+)/ ) { $leading_ws_i = $1; } + if ( $lineo =~ /^(\s+)/ ) { $leading_ws_o = $1; } + if ( $leading_ws_i ne $leading_ws_o ) { + $reason .= "; leading whitespace differs"; + if ( $leading_ws_i =~ /\t/ ) { + $reason .= "; input has tab char"; + } + } + else { + my ( $trailing_ws_i, $trailing_ws_o ) = ( "", "" ); + if ( $linei =~ /(\s+)$/ ) { $trailing_ws_i = $1; } + if ( $lineo =~ /(\s+)$/ ) { $trailing_ws_o = $1; } + if ( $trailing_ws_i ne $trailing_ws_o ) { + $reason .= "; trailing whitespace differs"; + } + } + $msg .= $reason . "\n"; + + # limit string display length + if ( $pos1 > 60 ) { + my $drop = $pos1 - 40; + $linei = "..." . substr( $linei, $drop ); + $lineo = "..." . substr( $lineo, $drop ); + $line_diff = " " . substr( $line_diff, $drop ); + } + $linei = $truncate->( $linei, 72 ); + $lineo = $truncate->( $lineo, 72 ); + $last_nonblank_line = $truncate->( $last_nonblank_line, 72 ); + + if ($last_nonblank_line) { + my $countm = $counti - 1; $msg .= <$counto:$lineo +$line_diff EOM - return $msg; - } - } + return $msg; + } ## end while + # no line differences found, but one file may have fewer lines if ( $counti > $counto ) { $msg .= <