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 = $?;