Merge branch 'es/chainlint-lineno'
Teach chainlint.pl to show corresponding line numbers when printing the source of a test. * es/chainlint-lineno: chainlint: prefix annotated test definition with line numbers chainlint: latch line numbers at which each token starts and ends chainlint: sidestep impoverished macOS "terminfo"
This commit is contained in:
commit
cf9721cc46
@ -94,7 +94,7 @@ check-chainlint:
|
||||
done \
|
||||
} >'$(CHAINLINTTMP_SQ)'/expect && \
|
||||
$(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests | \
|
||||
grep -v '^[ ]*$$' >'$(CHAINLINTTMP_SQ)'/actual && \
|
||||
sed -e 's/^[1-9][0-9]* //;/^[ ]*$$/d' >'$(CHAINLINTTMP_SQ)'/actual && \
|
||||
if test -f ../GIT-BUILD-OPTIONS; then \
|
||||
. ../GIT-BUILD-OPTIONS; \
|
||||
fi && \
|
||||
|
@ -67,6 +67,7 @@ sub new {
|
||||
bless {
|
||||
parser => $parser,
|
||||
buff => $s,
|
||||
lineno => 1,
|
||||
heretags => []
|
||||
} => $class;
|
||||
}
|
||||
@ -97,7 +98,9 @@ sub scan_op {
|
||||
sub scan_sqstring {
|
||||
my $self = shift @_;
|
||||
${$self->{buff}} =~ /\G([^']*'|.*\z)/sgc;
|
||||
return "'" . $1;
|
||||
my $s = $1;
|
||||
$self->{lineno} += () = $s =~ /\n/sg;
|
||||
return "'" . $s;
|
||||
}
|
||||
|
||||
sub scan_dqstring {
|
||||
@ -115,7 +118,7 @@ sub scan_dqstring {
|
||||
if ($c eq '\\') {
|
||||
$s .= '\\', last unless $$b =~ /\G(.)/sgc;
|
||||
$c = $1;
|
||||
next if $c eq "\n"; # line splice
|
||||
$self->{lineno}++, next if $c eq "\n"; # line splice
|
||||
# backslash escapes only $, `, ", \ in dq-string
|
||||
$s .= '\\' unless $c =~ /^[\$`"\\]$/;
|
||||
$s .= $c;
|
||||
@ -123,6 +126,7 @@ sub scan_dqstring {
|
||||
}
|
||||
die("internal error scanning dq-string '$c'\n");
|
||||
}
|
||||
$self->{lineno} += () = $s =~ /\n/sg;
|
||||
return $s;
|
||||
}
|
||||
|
||||
@ -137,6 +141,7 @@ sub scan_balanced {
|
||||
$depth--;
|
||||
last if $depth == 0;
|
||||
}
|
||||
$self->{lineno} += () = $s =~ /\n/sg;
|
||||
return $s;
|
||||
}
|
||||
|
||||
@ -163,8 +168,11 @@ sub swallow_heredocs {
|
||||
my $b = $self->{buff};
|
||||
my $tags = $self->{heretags};
|
||||
while (my $tag = shift @$tags) {
|
||||
my $start = pos($$b);
|
||||
my $indent = $tag =~ s/^\t// ? '\\s*' : '';
|
||||
$$b =~ /(?:\G|\n)$indent\Q$tag\E(?:\n|\z)/gc;
|
||||
my $body = substr($$b, $start, pos($$b) - $start);
|
||||
$self->{lineno} += () = $body =~ /\n/sg;
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,11 +180,12 @@ sub scan_token {
|
||||
my $self = shift @_;
|
||||
my $b = $self->{buff};
|
||||
my $token = '';
|
||||
my $start;
|
||||
my ($start, $startln);
|
||||
RESTART:
|
||||
$startln = $self->{lineno};
|
||||
$$b =~ /\G[ \t]+/gc; # skip whitespace (but not newline)
|
||||
$start = pos($$b) || 0;
|
||||
return ["\n", $start, pos($$b)] if $$b =~ /\G#[^\n]*(?:\n|\z)/gc; # comment
|
||||
$self->{lineno}++, return ["\n", $start, pos($$b), $startln, $startln] if $$b =~ /\G#[^\n]*(?:\n|\z)/gc; # comment
|
||||
while (1) {
|
||||
# slurp up non-special characters
|
||||
$token .= $1 if $$b =~ /\G([^\\;&|<>(){}'"\$\s]+)/gc;
|
||||
@ -188,20 +197,20 @@ RESTART:
|
||||
$token .= $self->scan_sqstring(), next if $c eq "'";
|
||||
$token .= $self->scan_dqstring(), next if $c eq '"';
|
||||
$token .= $c . $self->scan_dollar(), next if $c eq '$';
|
||||
$self->swallow_heredocs(), $token = $c, last if $c eq "\n";
|
||||
$self->{lineno}++, $self->swallow_heredocs(), $token = $c, last if $c eq "\n";
|
||||
$token = $self->scan_op($c), last if $c =~ /^[;&|<>]$/;
|
||||
$token = $c, last if $c =~ /^[(){}]$/;
|
||||
if ($c eq '\\') {
|
||||
$token .= '\\', last unless $$b =~ /\G(.)/sgc;
|
||||
$c = $1;
|
||||
next if $c eq "\n" && length($token); # line splice
|
||||
goto RESTART if $c eq "\n"; # line splice
|
||||
$self->{lineno}++, next if $c eq "\n" && length($token); # line splice
|
||||
$self->{lineno}++, goto RESTART if $c eq "\n"; # line splice
|
||||
$token .= '\\' . $c;
|
||||
next;
|
||||
}
|
||||
die("internal error scanning character '$c'\n");
|
||||
}
|
||||
return length($token) ? [$token, $start, pos($$b)] : undef;
|
||||
return length($token) ? [$token, $start, pos($$b), $startln, $self->{lineno}] : undef;
|
||||
}
|
||||
|
||||
# ShellParser parses POSIX shell scripts (with minor extensions for Bash). It
|
||||
@ -605,6 +614,7 @@ sub check_test {
|
||||
my $problems = $parser->{problems};
|
||||
return unless $emit_all || @$problems;
|
||||
my $c = main::fd_colors(1);
|
||||
my $lineno = $_[1]->[3];
|
||||
my $start = 0;
|
||||
my $checked = '';
|
||||
for (sort {$a->[1]->[2] <=> $b->[1]->[2]} @$problems) {
|
||||
@ -614,10 +624,12 @@ sub check_test {
|
||||
$start = $pos;
|
||||
}
|
||||
$checked .= substr($body, $start);
|
||||
$checked =~ s/^\n//;
|
||||
$checked =~ s/^/$lineno++ . ' '/mge;
|
||||
$checked =~ s/^\d+ \n//;
|
||||
$checked =~ s/(\s) \?!/$1?!/mg;
|
||||
$checked =~ s/\?! (\s)/?!$1/mg;
|
||||
$checked =~ s/(\?![^?]+\?!)/$c->{rev}$c->{red}$1$c->{reset}/mg;
|
||||
$checked =~ s/^\d+/$c->{dim}$&$c->{reset}/mg;
|
||||
$checked .= "\n" unless $checked =~ /\n$/;
|
||||
push(@{$self->{output}}, "$c->{blue}# chainlint: $title$c->{reset}\n$checked");
|
||||
}
|
||||
@ -649,25 +661,39 @@ if (eval {require Time::HiRes; Time::HiRes->import(); 1;}) {
|
||||
# thread and ignore %ENV changes in subthreads.
|
||||
$ENV{TERM} = $ENV{USER_TERM} if $ENV{USER_TERM};
|
||||
|
||||
my @NOCOLORS = (bold => '', rev => '', reset => '', blue => '', green => '', red => '');
|
||||
my @NOCOLORS = (bold => '', rev => '', dim => '', reset => '', blue => '', green => '', red => '');
|
||||
my %COLORS = ();
|
||||
sub get_colors {
|
||||
return \%COLORS if %COLORS;
|
||||
if (exists($ENV{NO_COLOR}) ||
|
||||
system("tput sgr0 >/dev/null 2>&1") != 0 ||
|
||||
system("tput bold >/dev/null 2>&1") != 0 ||
|
||||
system("tput rev >/dev/null 2>&1") != 0 ||
|
||||
system("tput setaf 1 >/dev/null 2>&1") != 0) {
|
||||
if (exists($ENV{NO_COLOR})) {
|
||||
%COLORS = @NOCOLORS;
|
||||
return \%COLORS;
|
||||
}
|
||||
%COLORS = (bold => `tput bold`,
|
||||
rev => `tput rev`,
|
||||
reset => `tput sgr0`,
|
||||
blue => `tput setaf 4`,
|
||||
green => `tput setaf 2`,
|
||||
red => `tput setaf 1`);
|
||||
chomp(%COLORS);
|
||||
if ($ENV{TERM} =~ /xterm|xterm-\d+color|xterm-new|xterm-direct|nsterm|nsterm-\d+color|nsterm-direct/) {
|
||||
%COLORS = (bold => "\e[1m",
|
||||
rev => "\e[7m",
|
||||
dim => "\e[2m",
|
||||
reset => "\e[0m",
|
||||
blue => "\e[34m",
|
||||
green => "\e[32m",
|
||||
red => "\e[31m");
|
||||
return \%COLORS;
|
||||
}
|
||||
if (system("tput sgr0 >/dev/null 2>&1") == 0 &&
|
||||
system("tput bold >/dev/null 2>&1") == 0 &&
|
||||
system("tput rev >/dev/null 2>&1") == 0 &&
|
||||
system("tput dim >/dev/null 2>&1") == 0 &&
|
||||
system("tput setaf 1 >/dev/null 2>&1") == 0) {
|
||||
%COLORS = (bold => `tput bold`,
|
||||
rev => `tput rev`,
|
||||
dim => `tput dim`,
|
||||
reset => `tput sgr0`,
|
||||
blue => `tput setaf 4`,
|
||||
green => `tput setaf 2`,
|
||||
red => `tput setaf 1`);
|
||||
return \%COLORS;
|
||||
}
|
||||
%COLORS = @NOCOLORS;
|
||||
return \%COLORS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user