diff --git a/mingw-w64-lcov/001-mingw-lcov1.12-handle-equals-signs.patch b/mingw-w64-lcov/001-mingw-lcov1.12-handle-equals-signs.patch new file mode 100644 index 0000000000..8ab09985bc --- /dev/null +++ b/mingw-w64-lcov/001-mingw-lcov1.12-handle-equals-signs.patch @@ -0,0 +1,23 @@ +Description: Handle "=====" as another form of zero. + gcov prints "=====" instead of "######" when an unexecuted line is + "reachable only by exceptional paths such as C++ exception handlers." + This should be handled the same as "######" for our purposes. +Author: Zack Weinberg +Last-Update: 2013-02-01 + +Index: lcov-1.12/bin/geninfo +=================================================================== +--- lcov-1.12.orig/bin/geninfo ++++ lcov-1.12/bin/geninfo +@@ -1771,8 +1771,9 @@ sub read_gcov_file($) + $number = (split(" ",substr($_, 0, 16)))[0]; + + # Check for zero count which is indicated +- # by ###### +- if ($number eq "######") { $number = 0; } ++ # by ###### or ===== ++ if ($number eq "######" or ++ $number eq "=====") { $number = 0; } + + if ($exclude_line) { + # Register uninstrumented line instead diff --git a/mingw-w64-lcov/002-mingw-lcov1.12-fix-undef-behaviour.patch b/mingw-w64-lcov/002-mingw-lcov1.12-fix-undef-behaviour.patch new file mode 100644 index 0000000000..3621fc8986 --- /dev/null +++ b/mingw-w64-lcov/002-mingw-lcov1.12-fix-undef-behaviour.patch @@ -0,0 +1,37 @@ +Author: Alastair McKinstry +Description: Fix for undefined behavior in perl5.20 +Origin: http://bugs.debian.org/761308 +Forwarded: no +Last-Updated: 2014-09-13 + +Index: lcov-1.12/bin/lcov +=================================================================== +--- lcov-1.12.orig/bin/lcov ++++ lcov-1.12/bin/lcov +@@ -224,7 +224,9 @@ Getopt::Long::Configure("default"); + # Remove spaces around rc options + my %new_opt_rc; + +- while (my ($key, $value) = each(%opt_rc)) { ++ my @keys = keys %opt_rc; ++ for my $key (@keys) { ++ my $value = $opt_rc{$key}; + $key =~ s/^\s+|\s+$//g; + $value =~ s/^\s+|\s+$//g; + +Index: lcov-1.12/bin/geninfo +=================================================================== +--- lcov-1.12.orig/bin/geninfo ++++ lcov-1.12/bin/geninfo +@@ -284,8 +284,9 @@ Getopt::Long::Configure("default"); + { + # Remove spaces around rc options + my %new_opt_rc; +- +- while (my ($key, $value) = each(%opt_rc)) { ++ my @keys = keys %opt_rc; ++ for my $key (@keys) { ++ my $value = $opt_rc{$key}; + $key =~ s/^\s+|\s+$//g; + $value =~ s/^\s+|\s+$//g; + diff --git a/mingw-w64-lcov/003-mingw-lcov-win32.patch b/mingw-w64-lcov/003-mingw-lcov-win32.patch new file mode 100644 index 0000000000..da97da0716 --- /dev/null +++ b/mingw-w64-lcov/003-mingw-lcov-win32.patch @@ -0,0 +1,414 @@ +diff --git a/bin/genhtml b/bin/genhtml +index d02c92c..2d56d57 100755 +--- a/bin/genhtml ++++ b/bin/genhtml +@@ -62,11 +62,15 @@ + # 2008-08-13 / Peter Oberparleiter: modified function coverage + # implementation (now enabled per default), + # introduced sorting option (enabled per default) ++# 2020-02-11 / David Garcin: improved Support for Win32 via $dir_separator ++# 2022-06-08 / Simon Sobisch: use make_path instead of system command and ++# devnull instead of /dev/null + # + + use strict; + use warnings; + use File::Basename; ++use File::Path qw(make_path); + use File::Temp qw(tempfile); + use Getopt::Long; + use Digest::MD5 qw(md5_base64); +@@ -308,7 +312,12 @@ our $lcov_branch_coverage = 0; + our $rc_desc_html = 0; # lcovrc: genhtml_desc_html + + our $cwd = cwd(); # Current working directory +- ++our $devnull = File::Spec->devnull(); ++our $dir_separator = "/"; ++if ($^O =~ /Win/) ++{ ++ $dir_separator = "\\"; ++} + + # + # Code entry point +@@ -580,12 +589,7 @@ if ($default_precision < 1 || $default_precision > 4) + # Make sure output_directory exists, create it if necessary + if ($output_directory) + { +- stat($output_directory); +- +- if (! -e _) +- { +- create_sub_dir($output_directory); +- } ++ create_sub_dir($output_directory); + } + + # Do something +@@ -1130,7 +1134,7 @@ sub process_dir($) + + # Match filenames which specify files in this directory, not including + # sub-directories +- foreach $filename (grep(/^\Q$abs_dir\E\/[^\/]*$/,keys(%info_data))) ++ foreach $filename (grep(/^\Q$abs_dir$dir_separator\E[^\Q$dir_separator\E]*$/,keys(%info_data))) + { + my $page_link; + my $func_link; +@@ -2409,7 +2413,7 @@ sub get_prefix($@) + $current = $_; + while ($current = shorten_prefix($current)) + { +- $current .= "/"; ++ $current .= $dir_separator; + + # Skip rest if the remaining prefix has already been + # added to hash +@@ -2427,7 +2431,7 @@ sub get_prefix($@) + my $dir = dirname($filename); + + for (my $i = 0; $i < $min_dir; $i++) { +- delete($prefix{$dir."/"}); ++ delete($prefix{$dir.$dir_separator}); + $dir = shorten_prefix($dir); + } + } +@@ -2463,7 +2467,7 @@ sub get_prefix($@) + } + } + +- $current =~ s/\/$//; ++ $current =~ s/\Q$dir_separator\E$//; + + return($current); + } +@@ -2477,10 +2481,11 @@ sub get_prefix($@) + + sub shorten_prefix($) + { +- my @list = split("/", $_[0]); ++ ++ my @list = split(/\Q$dir_separator\E/, $_[0]); + + pop(@list); +- return join("/", @list); ++ return join($dir_separator, @list); + } + + +@@ -2524,6 +2529,13 @@ sub get_relative_base_path($) + # Count number of /s in path + $index = ($_[0] =~ s/\//\//g); + ++ ++ # Count \s as well if under native Windows host ++ if ($^O =~ /Win/) ++ { ++ $index += ($_[0] =~ s/\\/\\/g); ++ } ++ + # Add a ../ to $result for each / in the directory path + 1 + for (; $index>=0; $index--) + { +@@ -2680,9 +2692,12 @@ sub get_date_string() + sub create_sub_dir($) + { + my ($dir) = @_; ++ stat($dir); + +- system("mkdir", "-p" ,$dir) +- and die("ERROR: cannot create directory $dir!\n"); ++ if (! -e _) ++ { ++ make_path ($dir) or die "Couldn't create $dir directory, $!"; ++ } + } + + +@@ -5809,7 +5824,7 @@ sub apply_prefix($@) + { + return "root"; + } +- if ($prefix ne "" && $filename =~ /^\Q$prefix\E\/(.*)$/) ++ if ($prefix ne "" && $filename =~ /^\Q$prefix$dir_separator\E(.*)$/) + { + return substr($filename, length($prefix) + 1); + } +@@ -5844,8 +5859,8 @@ sub system_no_output($@) + ($mode & 2) && open(OLD_STDERR, ">>&", "STDERR"); + + # Redirect to /dev/null +- ($mode & 1) && open(STDOUT, ">", "/dev/null"); +- ($mode & 2) && open(STDERR, ">", "/dev/null"); ++ ($mode & 1) && open(STDOUT, ">", $devnull); ++ ($mode & 2) && open(STDERR, ">", $devnull); + + system(@_); + $result = $?; +diff --git a/bin/geninfo b/bin/geninfo +index 31c0b57..219822d 100755 +--- a/bin/geninfo ++++ b/bin/geninfo +@@ -47,27 +47,33 @@ + # 2008-07-14 / Tom Zoerner: added --function-coverage command line option + # 2008-08-13 / Peter Oberparleiter: modified function coverage + # implementation (now enabled per default) ++# 2020-02-11 / David Garcin: use getcwd instead of system command ++# 2022-06-08 / Simon Sobisch: use move instead of system command ++# and devnull instead of /dev/null; ++# use canonpath instead of self-written path adjustment + # + + use strict; + use warnings; + use File::Basename; + use File::Spec::Functions qw /abs2rel catdir file_name_is_absolute splitdir +- splitpath catpath/; ++ splitpath catpath catdir canonpath/; + use File::Temp qw(tempfile tempdir); +-use File::Copy qw(copy); ++use File::Copy qw(copy move); + use Getopt::Long; + use Digest::MD5 qw(md5_base64); +-use Cwd qw/abs_path/; ++use Cwd qw/abs_path getcwd/; + use IO::Uncompress::Gunzip qw(gunzip $GunzipError); + use Module::Load; + use Module::Load::Conditional qw(check_install); + +-if( $^O eq "msys" ) ++ ++if ( $^O eq "msys" ) + { + require File::Spec::Win32; + } + ++ + # Constants + our $tool_dir = abs_path(dirname($0)); + our $lcov_version = 'LCOV version '.`"$tool_dir"/get_version.sh --full`; +@@ -161,6 +167,8 @@ our $BR_VEC_MAX = vec(pack('b*', 1 x $BR_VEC_WIDTH), 0, $BR_VEC_WIDTH); + + our $UNNAMED_BLOCK = -1; + ++our $devnull = File::Spec->devnull(); ++ + # Prototypes + sub print_usage(*); + sub transform_pattern($); +@@ -283,7 +291,7 @@ our $excl_line = "LCOV_EXCL_LINE"; + our $excl_br_line = "LCOV_EXCL_BR_LINE"; + our $excl_exception_br_line = "LCOV_EXCL_EXCEPTION_BR_LINE"; + +-our $cwd = `pwd`; ++our $cwd = getcwd(); + chomp($cwd); + + +@@ -839,7 +847,7 @@ sub gen_info($) + { + info("Scanning $directory for $ext files ...\n"); + +- @file_list = `find "$directory" $maxdepth $follow -name \\*$ext -type f -o -name \\*$ext -type l 2>/dev/null`; ++ @file_list = `find "$directory" $maxdepth $follow -name \\*$ext -type f -o -name \\*$ext -type l 2>$devnull`; + chomp(@file_list); + if (!@file_list) { + warn("WARNING: no $ext files found in $directory - ". +@@ -1164,8 +1172,8 @@ sub process_dafile($$) + { + # Need to rename empty data file to workaround + # gcov <= 3.2.x bug (Abort) +- system_no_output(3, "mv", "$da_filename", "$da_filename.ori") +- and die ("ERROR: cannot rename $da_filename\n"); ++ move("$da_filename", "$da_filename.ori") ++ or die ("ERROR: cannot rename $da_filename\n"); + } + + # Execute gcov command and suppress standard output +@@ -1174,8 +1182,8 @@ sub process_dafile($$) + + if ($da_renamed) + { +- system_no_output(3, "mv", "$da_filename.ori", "$da_filename") +- and die ("ERROR: cannot rename $da_filename.ori"); ++ move("$da_filename.ori", "$da_filename") ++ or die ("ERROR: cannot rename $da_filename.ori"); + } + + # Clean up temporary links +@@ -1518,7 +1526,7 @@ sub solve_relative_path($$) + my $result; + + # Convert from Windows path to msys path +- if( $^O eq "msys" ) ++ if ( $^O eq "msys" ) + { + # search for a windows drive letter at the beginning + ($volume, $directories, $filename) = File::Spec::Win32->splitpath( $dir ); +@@ -1538,39 +1546,34 @@ sub solve_relative_path($$) + + # transform to Unix style '/' path + $directories = File::Spec->catdir( @dirs ); +- $dir = File::Spec->catpath( '', $directories, $filename ); ++ $dir = catpath( '', $directories, $filename ); + } else { + # eliminate '\' path separators +- $dir = File::Spec->canonpath( $dir ); ++ $dir = canonpath( $dir ); + } + } +- +- $result = $dir; +- # Prepend path if not absolute +- if ($dir =~ /^[^\/]/) ++ else + { +- $result = "$path/$result"; ++ # Resolve relative names and for Win32 transform ++ # c/d\../e/f\g to Windows style c\d\..\e\f\g ++ # Note: other than before we do not replace ++ # x/../y sections into y any more, see perldoc for canonpath ++ # to learn why this is a bad idea (symlinks) ++ $path = canonpath($path); ++ $dir = canonpath($dir); + } + +- # Remove // +- $result =~ s/\/\//\//g; +- +- # Remove . +- while ($result =~ s/\/\.\//\//g) ++ # Prepend path if not absolute ++ if (file_name_is_absolute($dir)) + { +- } +- $result =~ s/\/\.$/\//g; +- +- # Remove trailing / +- $result =~ s/\/$//g; ++ $result = $dir; + +- # Solve .. +- while ($result =~ s/\/[^\/]+\/\.\.\//\//) ++ } ++ else + { ++ $result = catdir($path, $dir); + } + +- # Remove preceding .. +- $result =~ s/^\/\.\.\//\//g; + + return $result; + } +@@ -2169,7 +2172,7 @@ sub read_intermediate_json($$$) + + # Workaround for bug in MSYS GCC 9.x that encodes \ as \n in gcov JSON + # output +- if ($^O eq "msys" && $$basedir_ref =~ /\n/) { ++ if ( ($^O eq "msys") || ($^O =~ /Win/) && $$basedir_ref =~ /\n/) { + $$basedir_ref =~ s#\n#/#g; + } + +@@ -2793,8 +2796,8 @@ sub system_no_output($@) + } + } else { + # Redirect to /dev/null +- ($mode & 1) && open(STDOUT, ">", "/dev/null"); +- ($mode & 2) && open(STDERR, ">", "/dev/null"); ++ ($mode & 1) && open(STDOUT, ">", $devnull); ++ ($mode & 2) && open(STDERR, ">", $devnull); + } + + debug("system(".join(' ', @_).")\n"); +@@ -3531,6 +3534,7 @@ sub adjust_source_filenames($$$) + my $old_filename = $filename; + + # Convert to absolute canonical form ++ + $filename = solve_relative_path($base_dir, $filename); + + # Apply adjustment +diff --git a/bin/lcov b/bin/lcov +index 7c73ab3..545dfbd 100755 +--- a/bin/lcov ++++ b/bin/lcov +@@ -57,6 +57,9 @@ + # 2004-03-30 / Peter Oberparleiter: added --path option + # 2004-08-09 / Peter Oberparleiter: added configuration file support + # 2008-08-13 / Peter Oberparleiter: added function coverage support ++# 2020-02-11 / David Garcin: use getcwd instead of system command, ++# execute geninfo via perl for Win32 ++# 2022-06-08 / Simon Sobisch: use devnull instead of /dev/null + # + + use strict; +@@ -94,6 +97,8 @@ our $pkg_build_file = ".build_directory"; + our $BR_SUB = 0; + our $BR_ADD = 1; + ++our $devnull = File::Spec->devnull(); ++ + # Prototypes + sub print_usage(*); + sub check_options(); +@@ -156,7 +161,7 @@ our $version; # Version option flag + our $convert_filenames; # If set, convert filenames when applying diff + our $strip; # If set, strip leading directories when applying diff + our $temp_dir_name; # Name of temporary directory +-our $cwd = `pwd`; # Current working directory ++our $cwd = getcwd(); # Current working directory + our $data_stdout; # If set, indicates that data is written to stdout + our $follow; # If set, indicates that find shall follow links + our $diff_path = ""; # Path removed from tracefile when applying diff +@@ -612,7 +617,7 @@ sub userspace_reset() + { + info("Deleting all .da files in $current_dir". + ($no_recursion?"\n":" and subdirectories\n")); +- @file_list = `find "$current_dir" $maxdepth $follow -name \\*\\.da -type f -o -name \\*\\.gcda -type f 2>/dev/null`; ++ @file_list = `find "$current_dir" $maxdepth $follow -name \\*\\.da -type f -o -name \\*\\.gcda -type f 2>$devnull`; + chomp(@file_list); + foreach (@file_list) + { +@@ -907,6 +912,12 @@ sub lcov_geninfo(@) + @param = (@param, "--exclude", $_); + } + ++ if ($^O =~ /Win/) ++ { ++ # Native Windows can't deduce the interpreter from the shebang, ++ # prepend it to the command ++ @param = ($^X, @param) ++ } + system(@param) and exit($? >> 8); + } + +@@ -951,7 +962,7 @@ sub get_package($) + info("Reading package $file:\n"); + $file = abs_path($file); + chdir($dir); +- open(HANDLE, "-|", "tar xvfz '$file' 2>/dev/null") ++ open(HANDLE, "-|", "tar xvfz '$file' 2>$devnull") + or die("ERROR: could not process package $file\n"); + $count = 0; + while () { +@@ -1038,7 +1049,7 @@ sub create_package($$$;$) + my $cwd = getcwd(); + + # Check for availability of tar tool first +- system("tar --help > /dev/null") ++ system("tar --help > $devnull") + and die("ERROR: tar command not available\n"); + + # Print information about the package +@@ -4048,8 +4059,8 @@ sub system_no_output($@) + ($mode & 2) && open(OLD_STDERR, ">>&", "STDERR"); + + # Redirect to /dev/null +- ($mode & 1) && open(STDOUT, ">", "/dev/null"); +- ($mode & 2) && open(STDERR, ">", "/dev/null"); ++ ($mode & 1) && open(STDOUT, ">", $devnull); ++ ($mode & 2) && open(STDERR, ">", $devnull); + + system(@_); + $result = $?; diff --git a/mingw-w64-lcov/PKGBUILD b/mingw-w64-lcov/PKGBUILD new file mode 100644 index 0000000000..b8e45a3bf0 --- /dev/null +++ b/mingw-w64-lcov/PKGBUILD @@ -0,0 +1,36 @@ +# Contributor: Jordi De Groof +# Contributor: Andre Klitzing +# Contributor: Simon Sobisch + +_realname=lcov +pkgbase=mingw-w64-${_realname} +pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}") +pkgver=1.16 +pkgrel=1 +pkgdesc="front-end for GCC's coverage testing tool gcov" +arch=('any') +url="https://github.com/linux-test-project/lcov" +license=('GPL') +depends=("${MINGW_PACKAGE_PREFIX}-perl") +source=("https://github.com/linux-test-project/lcov/releases/download/v${pkgver}/${_realname}-${pkgver}.tar.gz" + "001-mingw-lcov1.12-handle-equals-signs.patch" + "002-mingw-lcov1.12-fix-undef-behaviour.patch" + "003-mingw-lcov-win32.patch") +sha256sums=('987031ad5528c8a746d4b52b380bc1bffe412de1f2b9c2ba5224995668e3240b' + '54728aa4e244d3662c65ba91fb486dc1d5c64d9d55745ee334c4131109dc233c' + 'ceaf41f7cc9cea5a6fc4b0385ffef10d1ab8812acd2a5b16dcd8d7bca7120488' + '2618246416784d36d48ff23398324eb39f34443c0dbc9ad3b61b100a5be33e7f') + +prepare() { + cd "${srcdir}/${_realname}-${pkgver}" + + patch -p1 -i ${srcdir}/001-mingw-lcov1.12-handle-equals-signs.patch + patch -p1 -i ${srcdir}/002-mingw-lcov1.12-fix-undef-behaviour.patch + patch -p1 -i ${srcdir}/003-mingw-lcov-win32.patch +} + +package() { + cd "${srcdir}/${_realname}-${pkgver}" + + make LCOV_PERL_PATH="${MINGW_PREFIX}/bin/perl" PREFIX="${MINGW_PREFIX}" DESTDIR="${pkgdir}" install +}