X-Git-Url: https://ruderich.org/simon/gitweb/?p=blhc%2Fblhc.git;a=blobdiff_plain;f=bin%2Fblhc;h=3611c6de4c3980fa743b201be179484705559590;hp=44fa3cee9d74821e8a883c226d55e657ae8bfd1c;hb=79d3a9eaaffbb1c593adf715fa5055a4a91ed0af;hpb=3c58bb7a1e0b6d9a67b8cba18affe657b2aecbbf diff --git a/bin/blhc b/bin/blhc index 44fa3ce..3611c6d 100755 --- a/bin/blhc +++ b/bin/blhc @@ -24,7 +24,7 @@ use warnings; use Getopt::Long (); use Text::ParseWords (); -our $VERSION = '0.11'; +our $VERSION = '0.12'; # CONSTANTS/VARIABLES @@ -341,18 +341,24 @@ my $option_color; # FUNCTIONS -# Only works for single-level arrays with no undef values. Thanks to perlfaq4. -sub array_equal { - my ($first_ref, $second_ref) = @_; +sub split_line { + my ($line) = @_; - return 0 if scalar @{$first_ref} != scalar @{$second_ref}; - - my $length = scalar @{$first_ref}; - for (my $i = 0; $i < $length; $i++) { - return 0 if $first_ref->[$i] ne $second_ref->[$i]; + my @work = ($line); + foreach my $delim (';', '&&', '||') { + my @x; + foreach (@work) { + push @x, Text::ParseWords::parse_line(qr/\Q$delim\E/, 1, $_); + } + @work = @x; } - return 1; + return map { + # Ensure newline at the line end - necessary for + # correct parsing later. + $_ =~ s/\s+$//; + $_ .= "\n"; + } @work; } sub error_flags { @@ -532,7 +538,7 @@ sub is_non_verbose_build { if (not (index($line, 'checking if you want to see long compiling messages... no') == 0 or $line =~ /^\s*\[?(?:CC|CCLD|C\+\+|CXX|CXXLD|LD|LINK)\]?\s+(.+?)$/ - or $line =~ /^\s*[Cc]ompiling\s+(.+?)(?:\.\.\.)?$/ + or $line =~ /^\s*[][\/0-9 ]*[Cc]ompiling\s+(.+?)(?:\.\.\.)?$/ or $line =~ /^\s*[Bb]uilding (?:program|shared library)\s+(.+?)$/ or $line =~ /^\s*\[[\d ]+%\] Building (?:C|CXX) object (.+?)$/)) { return 0; @@ -985,16 +991,12 @@ foreach my $file (@ARGV) { $non_verbose |= is_non_verbose_build($line, \$skip); next if $skip; - # One line may contain multiple commands (";"). Treat each one as - # single line. parse_line() is slow, only use it when necessary. - my @line = (index($line, ';') == -1) + # Treat each command as a single line so we don't ignore valid + # commands when handling false positives. split_line() is slow, only + # use it when necessary. + my @line = ($line !~ /(?:;|&&|\|\|)/) ? ($line) - : map { - # Ensure newline at the line end - necessary for - # correct parsing later. - $_ =~ s/\s+$//; - $_ .= "\n"; - } Text::ParseWords::parse_line(';', 1, $line); + : split_line($line); foreach my $line (@line) { if ($continuation) { $continuation = 0; @@ -1043,6 +1045,11 @@ foreach my $file (@ARGV) { # optional compiler options, don't allow # "everything" here to prevent false negatives \s*(?:\s-\S+)*\s*$}xo; + # `echo` is never a compiler command + next if $line =~ /^\s*echo\s/; + # Ignore calls to `make` because they can contain environment + # variables which look like compiler commands, e.g. CC=). + next if $line =~ /^\s*make\s/; # `moc-qt4`/`moc-qt5` contain '-I.../linux-g++' in their command # line (or similar for other architectures) which gets recognized # as a compiler line, but `moc-qt*` is only a preprocessor for Qt @@ -1078,6 +1085,8 @@ foreach my $file (@ARGV) { next if $line =~ m#(?:\b[0-9a-fA-F]{2,}\b\s*){5}#; # Meson build output next if $line =~ /^C\+\+ linker for the host machine: /; + # Embedded `gcc -print-*` commands + next if $line =~ /`$cc_regex_normal\s*[^`]*-print-\S+`/; # Check if additional hardening options were used. Used to ensure # they are used for the complete build.