2 # This is not a runnable script, it is a Perl module, a collection of variables, subroutines, etc.
3 # to be used in other scripts.
5 # To get help about exported variables and subroutines, please execute the following command:
9 # or see POD (Plain Old Documentation) imbedded to the source...
12 #//===----------------------------------------------------------------------===//
14 #// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
15 #// See https://llvm.org/LICENSE.txt for license information.
16 #// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
18 #//===----------------------------------------------------------------------===//
23 B<tools.pm> -- A collection of subroutines which are widely used in Perl scripts.
28 use lib "$FindBin::Bin/lib";
33 B<Note:> Because this collection is small and intended for widely using in particular project,
34 all variables and functions are exported by default.
36 B<Note:> I have some ideas how to improve this collection, but it is in my long-term plans.
37 Current shape is not ideal, but good enough to use.
46 use vars
qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS );
48 @ISA = qw( Exporter );
50 my @vars = qw( $tool );
51 my @utils = qw( check_opts validate );
52 my @opts = qw( get_options );
53 my @print = qw( debug info warning cmdline_error runtime_error question );
54 my @name = qw( get_vol get_dir get_file get_name get_ext cat_file cat_dir );
55 my @file = qw( which abs_path rel_path real_path make_dir clean_dir copy_dir move_dir del_dir change_dir copy_file move_file del_file );
56 my @io = qw( read_file write_file );
57 my @exec = qw( execute backticks );
58 my @string = qw{ pad
};
59 @EXPORT = ( @utils, @opts, @vars, @print, @name, @file, @io, @exec, @string );
67 # Not available on some machines: use IO::Zlib;
76 use POSIX
qw{ :fcntl_h
:errno_h
};
82 use vars
qw( $tool $verbose $timestamps );
83 $tool = $FindBin::Script;
85 my @warning = ( sub {}, \&warning, \&runtime_error );
88 sub check_opts(\%$;$) {
90 my $opts = shift( @_ ); # Reference to hash containing real options and their values.
91 my $good = shift( @_ ); # Reference to an array containing all known option names.
92 my $msg = shift( @_ ); # Optional (non-mandatory) message.
94 if ( not defined( $msg ) ) {
95 $msg = "unknown option(s) passed"; # Default value for $msg.
98 # I'll use these hashes as sets of options.
99 my %good = map( ( $_ => 1 ), @$good ); # %good now is filled with all known options.
100 my %bad; # %bad is empty.
102 foreach my $opt ( keys( %$opts ) ) { # For each real option...
103 if ( not exists( $good{ $opt } ) ) { # Look its name in the set of known options...
104 $bad{ $opt } = 1; # Add unknown option to %bad set.
105 delete( $opts->{ $opt } ); # And delete original option.
108 if ( %bad ) { # If %bad set is not empty...
109 my @caller = caller( 1 ); # Issue a warning.
110 local $Carp::CarpLevel = 2;
111 Carp::cluck( $caller[ 3 ] . ": " . $msg . ": " . join( ", ", sort( keys( %bad ) ) ) );
119 # --------------------------------------------------------------------------------------------------
121 # Check subroutine arguments.
123 # my %opts = validate( params => \@_, spec => { ... }, caller => n );
125 # params -- A reference to subroutine's actual arguments.
126 # spec -- Specification of expected arguments.
129 # A hash of validated options.
131 # I would like to use Params::Validate module, but it is not a part of default Perl
132 # distribution, so I cannot rely on it. This subroutine resembles to some extent to
133 # Params::Validate::validate_with().
134 # Specification of expected arguments:
135 # { $opt => { type => $type, default => $default }, ... }
136 # $opt -- String, option name.
137 # $type -- String, expected type(s). Allowed values are "SCALAR", "UNDEF", "BOOLEAN",
138 # "ARRAYREF", "HASHREF", "CODEREF". Multiple types may listed using bar:
139 # "SCALAR|ARRAYREF". The type string is case-insensitive.
140 # $default -- Default value for an option. Will be used if option is not specified or
145 my %opts = @_; # Temporary use %opts for parameters of `validate' subroutine.
146 my $params = $opts{ params };
147 my $caller = ( $opts{ caller } or 0 ) + 1;
148 my $spec = $opts{ spec };
149 undef( %opts ); # Ok, Clean %opts, now we will collect result of the subroutine.
151 # Find out caller package, filename, line, and subroutine name.
152 my ( $pkg, $file, $line, $subr ) = caller( $caller );
153 my @errors; # We will collect errors in array not to stop on the first found error.
156 my $msg = shift( @_ );
157 push( @errors, "$msg at $file line $line.\n" );
163 my $opt = shift( @$params );
164 if ( not exists( $spec->{ $opt } ) ) {
165 $error->( "Invalid option `$opt'" );
166 shift( @$params ); # Skip value of unknow option.
169 # Check option value exists.
170 if ( not @$params ) {
171 $error->( "Option `$opt' does not have a value" );
174 my $val = shift( @$params );
175 # Check option value type.
176 if ( exists( $spec->{ $opt }->{ type } ) ) {
177 # Type specification exists. Check option value type.
179 if ( ref( $val ) ne "" ) {
180 $actual_type = ref( $val ) . "REF";
182 $actual_type = ( defined( $val ) ? "SCALAR" : "UNDEF" );
184 my @wanted_types = split( m{\|}, lc( $spec->{ $opt }->{ type } ) );
185 my $wanted_types = join( "|", map( $_ eq "boolean" ? "scalar|undef" : quotemeta( $_ ), @wanted_types ) );
186 if ( $actual_type !~ m{\A(?:$wanted_types)\z}i ) {
187 $actual_type = lc( $actual_type );
188 $wanted_types = lc( join( " or ", map( "`$_'", @wanted_types ) ) );
189 $error->( "Option `$opt' value type is `$actual_type' but expected to be $wanted_types" );
193 if ( exists( $spec->{ $opt }->{ values } ) ) {
194 my $values = $spec->{ $opt }->{ values };
195 if ( not grep( $_ eq $val, @$values ) ) {
196 $values = join( ", ", map( "`$_'", @$values ) );
197 $error->( "Option `$opt' value is `$val' but expected to be one of $values" );
201 $opts{ $opt } = $val;
204 # Assign default values.
205 foreach my $opt ( keys( %$spec ) ) {
206 if ( not defined( $opts{ $opt } ) and exists( $spec->{ $opt }->{ default } ) ) {
207 $opts{ $opt } = $spec->{ $opt }->{ default };
211 # If we found any errors, raise them.
213 die join( "", @errors );
220 # =================================================================================================
221 # Get option helpers.
222 # =================================================================================================
224 =head2 Get option helpers.
228 # -------------------------------------------------------------------------------------------------
234 get_options( @arguments )
238 It is very simple wrapper arounf Getopt::Long::GetOptions. It passes all arguments to GetOptions,
239 and add definitions for standard help options: --help, --doc, --verbose, and --quiet.
240 When GetOptions finishes, this subroutine checks exit code, if it is non-zero, standard error
241 message is issued and script terminated.
243 If --verbose or --quiet option is specified, C<tools.pm_verbose> environment variable is set.
244 It is the way to propagate verbose/quiet mode to callee Perl scripts.
250 Getopt::Long::Configure( "no_ignore_case" );
251 Getopt::Long::GetOptions(
252 "h0|usage" => sub { Pod::Usage::pod2usage( -exitval => 0, -verbose => 0 ); },
253 "h1|h|help" => sub { Pod::Usage::pod2usage( -exitval => 0, -verbose => 1 ); },
254 "h2|doc|manual" => sub { Pod::Usage::pod2usage( -exitval => 0, -verbose => 2 ); },
255 "version" => sub { print( "$tool version $main::VERSION\n" ); exit( 0 ); },
256 "v|verbose" => sub { ++ $verbose; $ENV{ "tools.pm_verbose" } = $verbose; },
257 "quiet" => sub { -- $verbose; $ENV{ "tools.pm_verbose" } = $verbose; },
258 "with-timestamps" => sub { $timestamps = 1; $ENV{ "tools.pm_timestamps" } = $timestamps; },
259 @_, # Caller arguments are at the end so caller options overrides standard.
260 ) or cmdline_error();
265 # =================================================================================================
267 # =================================================================================================
271 =head2 Print utilities.
273 Each of the print subroutines prepends each line of its output with the name of current script and
274 the type of information, for example:
276 info( "Writing file..." );
280 <script>: (i): Writing file...
284 warning( "File does not exist!" );
288 <script>: (!): File does not exist!
290 Here are exported items:
294 # -------------------------------------------------------------------------------------------------
296 sub _format_message($\@;$) {
298 my $prefix = shift( @_ );
299 my $args = shift( @_ );
300 my $no_eol = shift( @_ ); # Do not append "\n" to the last line.
305 my ( $sec, $min, $hour, $day, $month, $year ) = gmtime();
308 $ts = sprintf( "%04d-%02d-%02d %02d:%02d:%02d UTC: ", $year, $month, $day, $hour, $min, $sec );
310 for my $i ( 1 .. @$args ) {
311 my @lines = split( "\n", $args->[ $i - 1 ] );
312 for my $j ( 1 .. @lines ) {
313 my $line = $lines[ $j - 1 ];
314 my $last_line = ( ( $i == @$args ) and ( $j == @lines ) );
315 my $eol = ( ( substr( $line, -1 ) eq "\n" ) or defined( $no_eol ) ? "" : "\n" );
316 $message .= "$ts$tool: ($prefix) " . $line . $eol;
321 }; # sub _format_message
323 #--------------------------------------------------------------------------------------------------
335 Package variable. It determines verbosity level, which affects C<warning()>, C<info()>, and
336 C<debug()> subroutines .
338 The variable gets initial value from C<tools.pm_verbose> environment variable if it is exists.
339 If the environment variable does not exist, variable is set to 2.
341 Initial value may be overridden later directly or by C<get_options> function.
345 $verbose = exists( $ENV{ "tools.pm_verbose" } ) ? $ENV{ "tools.pm_verbose" } : 2;
347 #--------------------------------------------------------------------------------------------------
359 Package variable. It determines whether C<debug()>, C<info()>, C<warning()>, C<runtime_error()>
360 subroutines print timestamps or not.
362 The variable gets initial value from C<tools.pm_timestamps> environment variable if it is exists.
363 If the environment variable does not exist, variable is set to false.
365 Initial value may be overridden later directly or by C<get_options()> function.
369 $timestamps = exists( $ENV{ "tools.pm_timestamps" } ) ? $ENV{ "tools.pm_timestamps" } : 0;
371 # -------------------------------------------------------------------------------------------------
383 If verbosity level is 3 or higher, print debug information to the stderr, prepending it with "(#)"
390 if ( $verbose >= 3 ) {
392 STDERR->print( _format_message( "#", @_ ) );
398 #--------------------------------------------------------------------------------------------------
410 If verbosity level is 2 or higher, print information to the stderr, prepending it with "(i)" prefix.
416 if ( $verbose >= 2 ) {
418 STDERR->print( _format_message( "i", @_ ) );
423 #--------------------------------------------------------------------------------------------------
433 If verbosity level is 1 or higher, issue a warning, prepending it with "(!)" prefix.
439 if ( $verbose >= 1 ) {
441 warn( _format_message( "!", @_ ) );
446 # -------------------------------------------------------------------------------------------------
452 cmdline_error( @message )
456 Print error message and exit the program with status 2.
458 This function is intended to complain on command line errors, e. g. unknown
459 options, invalid arguments, etc.
463 sub cmdline_error(;$) {
465 my $message = shift( @_ );
467 if ( defined( $message ) ) {
468 if ( substr( $message, -1, 1 ) ne "\n" ) {
475 die $message . "Try --help option for more information.\n";
477 }; # sub cmdline_error
479 # -------------------------------------------------------------------------------------------------
485 runtime_error( @message )
489 Print error message and exits the program with status 3.
491 This function is intended to complain on runtime errors, e. g.
492 directories which are not found, non-writable files, etc.
496 sub runtime_error(@) {
499 die _format_message( "x", @_ );
501 }; # sub runtime_error
503 #--------------------------------------------------------------------------------------------------
509 question( $prompt; $answer, $choices )
513 Print $promp to the stderr, prepending it with "question:" prefix. Read a line from stdin, chop
514 "\n" from the end, it is answer.
516 If $answer is defined, it is treated as first user input.
518 If $choices is specified, it could be a regexp for validating user input, or a string. In latter
519 case it interpreted as list of characters, acceptable (case-insensitive) choices. If user enters
520 non-acceptable answer, question continue asking until answer is acceptable.
521 If $choices is not specified, any answer is acceptable.
523 In case of end-of-file (or Ctrl+D pressed by user), $answer is C<undef>.
528 question( "Save file [yn]? ", $answer, "yn" );
529 # We accepts only "y", "Y", "n", or "N".
530 question( "Press enter to continue or Ctrl+C to abort..." );
531 # We are not interested in answer value -- in case of Ctrl+C the script will be terminated,
532 # otherwise we continue execution.
533 question( "File name? ", $answer );
534 # Any answer is acceptable.
538 sub question($;\$$) {
540 my $prompt = shift( @_ );
541 my $answer = shift( @_ );
542 my $choices = shift( @_ );
543 my $a = ( defined( $answer ) ? $$answer : undef );
545 if ( ref( $choices ) eq "Regexp" ) {
546 # It is already a regular expression, do nothing.
547 } elsif ( defined( $choices ) ) {
548 # Convert string to a regular expression.
549 $choices = qr/[@{ [ quotemeta( $choices ) ] }]/i;
553 STDERR->print( _format_message( "?", @{ [ $prompt ] }, "no_eol" ) );
555 if ( defined( $a ) ) {
556 STDOUT->print( $a . "\n" );
560 if ( not defined( $a ) ) {
564 if ( not defined( $choices ) or ( $a =~ m/^$choices$/ ) ) {
569 if ( defined( $answer ) ) {
575 # -------------------------------------------------------------------------------------------------
577 # Returns volume part of path.
580 my $path = shift( @_ );
581 my ( $vol, undef, undef ) = File::Spec->splitpath( $path );
586 # Returns directory part of path.
589 my $path = File::Spec->canonpath( shift( @_ ) );
590 my ( $vol, $dir, undef ) = File::Spec->splitpath( $path );
591 my @dirs = File::Spec->splitdir( $dir );
593 $dir = File::Spec->catdir( @dirs );
594 $dir = File::Spec->catpath( $vol, $dir, undef );
599 # Returns file part of path.
602 my $path = shift( @_ );
603 my ( undef, undef, $file ) = File::Spec->splitpath( $path );
608 # Returns file part of path without last suffix.
611 my $path = shift( @_ );
612 my ( undef, undef, $file ) = File::Spec->splitpath( $path );
613 $file =~ s{\.[^.]*\z}{};
618 # Returns last suffix of file part of path.
621 my $path = shift( @_ );
622 my ( undef, undef, $file ) = File::Spec->splitpath( $path );
624 if ( $file =~ m{(\.[^.]*)\z} ) {
633 my $path = shift( @_ );
634 my $file = pop( @_ );
637 my ( $vol, $dirs ) = File::Spec->splitpath( $path, "no_file" );
638 @dirs = ( File::Spec->splitdir( $dirs ), @dirs );
639 $dirs = File::Spec->catdir( @dirs );
640 $path = File::Spec->catpath( $vol, $dirs, $file );
648 my $path = shift( @_ );
651 my ( $vol, $dirs ) = File::Spec->splitpath( $path, "no_file" );
652 @dirs = ( File::Spec->splitdir( $dirs ), @dirs );
653 $dirs = File::Spec->catdir( @dirs );
654 $path = File::Spec->catpath( $vol, $dirs, "" );
660 # =================================================================================================
661 # File and directory manipulation subroutines.
662 # =================================================================================================
664 =head2 File and directory manipulation subroutines.
670 # -------------------------------------------------------------------------------------------------
672 =item C<which( $file, @options )>
674 Searches for specified executable file in the (specified) directories.
675 Raises a runtime eroror if no executable file found. Returns a full path of found executable(s).
681 =item C<-all> =E<gt> I<bool>
683 Do not stop on the first found file. Note, that list of full paths is returned in this case.
685 =item C<-dirs> =E<gt> I<ref_to_array>
687 Specify directory list to search through. If option is not passed, PATH environment variable
688 is used for directory list.
690 =item C<-exec> =E<gt> I<bool>
692 Whether check for executable files or not. By default, C<which> searches executable files.
693 However, on Cygwin executable check never performed.
699 Look for "echo" in the directories specified in PATH:
701 my $echo = which( "echo" );
703 Look for all occurrences of "cp" in the PATH:
705 my @cps = which( "cp", -all => 1 );
707 Look for the first occurrence of "icc" in the specified directories:
709 my $icc = which( "icc", -dirs => [ ".", "/usr/local/bin", "/usr/bin", "/bin" ] );
715 my $file = shift( @_ );
718 check_opts( %opts, [ qw( -all -dirs -exec ) ] );
719 if ( $opts{ -all
} and not wantarray() ) {
720 local $Carp::CarpLevel
= 1;
721 Carp
::cluck
( "`-all' option passed to `which' but list is not expected" );
723 if ( not defined( $opts{ -exec } ) ) {
727 my $dirs = ( exists( $opts{ -dirs
} ) ?
$opts{ -dirs
} : [ File
::Spec
->path() ] );
731 if ( $^O
eq "MSWin32" and $opts{ -exec } ) {
732 if ( defined( $ENV{ PATHEXT
} ) ) {
733 push( @exts, split( ";", $ENV{ PATHEXT
} ) );
735 # If PATHEXT does not exist, use default value.
736 push( @exts, qw{ .COM
.EXE
.BAT
.CMD
} );
741 foreach my $dir ( @
$dirs ) {
742 foreach my $ext ( @exts ) {
743 my $path = File
::Spec
->catfile( $dir, $file . $ext );
745 # Executable bit is not reliable on Cygwin, do not check it.
746 if ( not $opts{ -exec } or -x
$path or $^O
eq "cygwin" ) {
747 push( @found, $path );
748 if ( not $opts{ -all
} ) {
757 # TBD: We need to introduce an option for conditional enabling this error.
758 # runtime_error( "Could not find \"$file\" executable file in PATH." );
761 # TBD: Issue a warning?
764 if ( $opts{ -all
} ) {
772 # -------------------------------------------------------------------------------------------------
774 =item C<abs_path( $path, $base )>
776 Return absolute path for an argument.
778 Most of the work is done by C<File::Spec->rel2abs()>. C<abs_path()> additionally collapses
779 C<dir1/../dir2> to C<dir2>.
781 It is not so naive and made intentionally. For example on Linux* OS in Bash if F<link/> is a symbolic
782 link to directory F<some_dir/>
787 brings you back to F<link/>'s parent, not to parent of F<some_dir/>,
793 my ( $path, $base ) = @_;
794 $path = File
::Spec
->rel2abs( $path, ( defined( $base ) ?
$base : $ENV{ PWD
} ) );
795 my ( $vol, $dir, $file ) = File
::Spec
->splitpath( $path );
796 while ( $dir =~ s{/(?!\.\.)[^/]*/\.\.(?:/|\z)}{/} ) {
798 $path = File
::Spec
->canonpath( File
::Spec
->catpath( $vol, $dir, $file ) );
803 # -------------------------------------------------------------------------------------------------
805 =item C<rel_path( $path, $base )>
807 Return relative path for an argument.
813 my ( $path, $base ) = @_;
814 $path = File
::Spec
->abs2rel( abs_path
( $path ), $base );
819 # -------------------------------------------------------------------------------------------------
821 =item C<real_path( $dir )>
823 Return real absolute path for an argument. In the result all relative components (F<.> and F<..>)
824 and U<symbolic links are resolved>.
826 In most cases it is not what you want. Consider using C<abs_path> first.
828 C<abs_path> function from B<Cwd> module works with directories only. This function works with files
829 as well. But, if file is a symbolic link, function does not resolve it (yet).
831 The function uses C<runtime_error> to raise an error if something wrong.
837 my $orig_path = shift( @_ );
840 if ( not -e
$orig_path ) {
841 $message = "\"$orig_path\" does not exists";
843 # Cwd::abs_path does not work with files, so in this case we should handle file separately.
845 if ( not -d
$orig_path ) {
846 ( my $vol, my $dir, $file ) = File
::Spec
->splitpath( File
::Spec
->rel2abs( $orig_path ) );
847 $orig_path = File
::Spec
->catpath( $vol, $dir );
850 local $SIG{ __WARN__
} = sub { $message = $_[ 0 ]; };
851 $real_path = Cwd
::abs_path
( $orig_path );
853 if ( defined( $file ) ) {
854 $real_path = File
::Spec
->catfile( $real_path, $file );
857 if ( not defined( $real_path ) or $message ne "" ) {
858 $message =~ s/^stat\(.*\): (.*)\s+at .*? line \d+\s*\z/$1/;
859 runtime_error
( "Could not find real path for \"$orig_path\"" . ( $message ne "" ?
": $message" : "" ) );
865 # -------------------------------------------------------------------------------------------------
867 =item C<make_dir( $dir, @options )>
871 This function makes a directory. If necessary, more than one level can be created.
872 If directory exists, warning issues (the script behavior depends on value of
873 C<-warning_level> option). If directory creation fails or C<$dir> exists but it is not a
874 directory, error issues.
882 The numeric mode for new directories, 0750 (rwxr-x---) by default.
890 my $dir = shift( @_ );
895 parents
=> { type
=> "boolean", default => 1 },
896 mode
=> { type
=> "scalar", default => 0777 },
900 my $prefix = "Could not create directory \"$dir\"";
905 runtime_error
( "$prefix: it exists, but not a directory." );
909 File
::Path
::mkpath
( $dir, 0, $opts{ mode
} );
912 $@
=~ s{\s+at (?:[a-zA-Z0-9 /_.]*/)?tools\.pm line \d+\s*}{};
913 runtime_error
( "$prefix: $@" );
915 if ( not -d
$dir ) { # Just in case, check it one more time...
916 runtime_error
( "$prefix." );
922 # -------------------------------------------------------------------------------------------------
924 =item C<copy_dir( $src_dir, $dst_dir, @options )>
926 Copy directory recursively.
928 This function copies a directory recursively.
929 If source directory does not exist or not a directory, error issues.
937 Overwrite destination directory, if it exists.
945 my $src = shift( @_ );
946 my $dst = shift( @_ );
948 my $prefix = "Could not copy directory \"$src\" to \"$dst\"";
951 runtime_error
( "$prefix: \"$src\" does not exist." );
954 runtime_error
( "$prefix: \"$src\" is not a directory." );
958 if ( $opts{ -overwrite
} ) {
961 runtime_error
( "$prefix: \"$dst\" already exists." );
964 runtime_error
( "$prefix: \"$dst\" is not a directory." );
968 execute
( [ "cp", "-R", $src, $dst ] );
972 # -------------------------------------------------------------------------------------------------
974 =item C<move_dir( $src_dir, $dst_dir, @options )>
984 Overwrite destination directory, if it exists.
992 my $src = shift( @_ );
993 my $dst = shift( @_ );
995 my $prefix = "Could not copy directory \"$src\" to \"$dst\"";
998 runtime_error
( "$prefix: \"$src\" does not exist." );
1000 if ( not -d
$src ) {
1001 runtime_error
( "$prefix: \"$src\" is not a directory." );
1005 if ( $opts{ -overwrite
} ) {
1008 runtime_error
( "$prefix: \"$dst\" already exists." );
1011 runtime_error
( "$prefix: \"$dst\" is not a directory." );
1015 execute
( [ "mv", $src, $dst ] );
1019 # -------------------------------------------------------------------------------------------------
1021 =item C<clean_dir( $dir, @options )>
1023 Clean a directory: delete all the entries (recursively), but leave the directory.
1029 =item C<-force> => bool
1031 If a directory is not writable, try to change permissions first, then clean it.
1033 =item C<-skip> => regexp
1035 Regexp. If a directory entry mached the regexp, it is skipped, not deleted. (As a subsequence,
1036 a directory containing skipped entries is not deleted.)
1045 our %_clean_dir_opts;
1047 my $skip = $_clean_dir_opts{ skip
}; # Regexp.
1048 my $skipped = 0; # Number of skipped files.
1049 my $prefix = "Cleaning `$dir' failed:";
1050 my @stat = stat( $dir );
1051 my $mode = $stat[ 2 ];
1053 runtime_error
( $prefix, "Cannot stat `$dir': $!" );
1056 runtime_error
( $prefix, "It is not a directory." );
1058 if ( not -w _
) { # Directory is not writable.
1059 if ( not -o _
or not $_clean_dir_opts{ force
} ) {
1060 runtime_error
( $prefix, "Directory is not writable." );
1062 # Directory is not writable but mine. Try to change permissions.
1063 chmod( $mode | S_IWUSR
, $dir )
1064 or runtime_error
( $prefix, "Cannot make directory writable: $!" );
1066 my $handle = IO
::Dir
->new( $dir ) or runtime_error
( $prefix, "Cannot read directory: $!" );
1067 my @entries = File
::Spec
->no_upwards( $handle->read() );
1068 $handle->close() or runtime_error
( $prefix, "Cannot read directory: $!" );
1069 foreach my $entry ( @entries ) {
1070 my $path = cat_file
( $dir, $entry );
1071 if ( defined( $skip ) and $entry =~ $skip ) {
1075 unlink( $path ) or runtime_error
( $prefix, "Cannot delete symlink `$path': $!" );
1077 stat( $path ) or runtime_error
( $prefix, "Cannot stat `$path': $! " );
1081 my $rc = _clean_dir
( $path );
1083 rmdir( $path ) or runtime_error
( $prefix, "Cannot delete directory `$path': $!" );
1087 runtime_error
( $prefix, "`$path' is neither a file nor a directory." );
1097 my $dir = shift( @_ );
1098 our %_clean_dir_opts;
1099 local %_clean_dir_opts =
1103 skip
=> { type
=> "regexpref" },
1104 force
=> { type
=> "boolean" },
1107 my $skipped = _clean_dir
( $dir );
1112 # -------------------------------------------------------------------------------------------------
1114 =item C<del_dir( $dir, @options )>
1116 Delete a directory recursively.
1118 This function deletes a directory. If directory can not be deleted or it is not a directory, error
1119 message issues (and script exists).
1131 my $dir = shift( @_ );
1133 my $prefix = "Deleting directory \"$dir\" failed";
1134 our %_clean_dir_opts;
1135 local %_clean_dir_opts =
1139 force
=> { type
=> "boolean" },
1143 if ( not -e
$dir ) {
1147 if ( not -d
$dir ) {
1148 runtime_error
( "$prefix: it is not a directory." );
1151 rmdir( $dir ) or runtime_error
( "$prefix." );
1155 # -------------------------------------------------------------------------------------------------
1157 =item C<change_dir( $dir )>
1159 Change current directory.
1161 If any error occurred, error issues and script exits.
1167 my $dir = shift( @_ );
1170 or runtime_error
( "Could not chdir to \"$dir\": $!" );
1175 # -------------------------------------------------------------------------------------------------
1177 =item C<copy_file( $src_file, $dst_file, @options )>
1181 This function copies a file. If source does not exist or is not a file, error issues.
1189 Overwrite destination file, if it exists.
1195 sub copy_file
($$@
) {
1197 my $src = shift( @_ );
1198 my $dst = shift( @_ );
1200 my $prefix = "Could not copy file \"$src\" to \"$dst\"";
1202 if ( not -e
$src ) {
1203 runtime_error
( "$prefix: \"$src\" does not exist." );
1205 if ( not -f
$src ) {
1206 runtime_error
( "$prefix: \"$src\" is not a file." );
1210 if ( $opts{ -overwrite
} ) {
1213 runtime_error
( "$prefix: \"$dst\" already exists." );
1216 runtime_error
( "$prefix: \"$dst\" is not a file." );
1220 File
::Copy
::copy
( $src, $dst ) or runtime_error
( "$prefix: $!" );
1221 # On Windows* OS File::Copy preserves file attributes, but on Linux* OS it doesn't.
1222 # So we should do it manually...
1223 if ( $^O
=~ m/^linux\z/ ) {
1224 my $mode = ( stat( $src ) )[ 2 ]
1225 or runtime_error
( "$prefix: cannot get status info for source file." );
1226 chmod( $mode, $dst )
1227 or runtime_error
( "$prefix: cannot change mode of destination file." );
1232 # -------------------------------------------------------------------------------------------------
1234 sub move_file
($$@
) {
1236 my $src = shift( @_ );
1237 my $dst = shift( @_ );
1239 my $prefix = "Could not move file \"$src\" to \"$dst\"";
1241 check_opts
( %opts, [ qw( -overwrite ) ] );
1243 if ( not -e
$src ) {
1244 runtime_error
( "$prefix: \"$src\" does not exist." );
1246 if ( not -f
$src ) {
1247 runtime_error
( "$prefix: \"$src\" is not a file." );
1251 if ( $opts{ -overwrite
} ) {
1254 runtime_error
( "$prefix: \"$dst\" already exists." );
1257 runtime_error
( "$prefix: \"$dst\" is not a file." );
1261 File
::Copy
::move
( $src, $dst ) or runtime_error
( "$prefix: $!" );
1265 # -------------------------------------------------------------------------------------------------
1268 my $files = shift( @_ );
1269 if ( ref( $files ) eq "" ) {
1270 $files = [ $files ];
1272 foreach my $file ( @
$files ) {
1273 debug
( "Deleting file `$file'..." );
1274 my $rc = unlink( $file );
1275 if ( $rc == 0 && $! != ENOENT
) {
1276 # Reporn an error, but ignore ENOENT, because the goal is achieved.
1277 runtime_error
( "Deleting file `$file' failed: $!" );
1282 # -------------------------------------------------------------------------------------------------
1288 # =================================================================================================
1289 # File I/O subroutines.
1290 # =================================================================================================
1292 =head2 File I/O subroutines.
1296 #--------------------------------------------------------------------------------------------------
1302 read_file( $file, @options )
1306 Read file and return its content. In scalar context function returns a scalar, in list context
1307 function returns list of lines.
1309 Note: If the last of file does not terminate with newline, function will append it.
1317 A name or handle of file to read from.
1327 If true, file treats as a binary file: no newline conversion, no truncating trailing space, no
1328 newline removing performed. Entire file returned as a scalar.
1332 This option is allowed only in binary mode. Option's value should be a reference to a scalar.
1333 If option present, file content placed to pointee scalar and function returns true (1).
1337 If true, newline characters are removed from file content. By default newline characters remain.
1338 This option is not applicable in binary mode.
1340 =item B<-keep_trailing_space>
1342 If true, trainling space remain at the ends of lines. By default all trailing spaces are removed.
1343 This option is not applicable in binary mode.
1349 Return file as single line, remove trailing spaces.
1351 my $bulk = read_file( "message.txt" );
1353 Return file as list of lines with removed trailing space and
1356 my @bulk = read_file( "message.txt", -chomp => 1 );
1360 my $bulk = read_file( "message.txt", -binary => 1 );
1362 Read a big binary file:
1365 read_file( "big_binary_file", -binary => 1, -bulk => \$bulk );
1367 Read from standard input:
1369 my @bulk = read_file( \*STDIN );
1375 my $file = shift( @_ ); # The name or handle of file to read from.
1376 my %opts = @_; # Options.
1381 my $error = \
&runtime_error
;
1383 my @binopts = qw( -binary -error -bulk ); # Options available in binary mode.
1384 my @txtopts = qw( -binary -error -keep_trailing_space -chomp -layer ); # Options available in text (non-binary) mode.
1385 check_opts
( %opts, [ @binopts, @txtopts ] );
1386 if ( $opts{ -binary
} ) {
1387 check_opts
( %opts, [ @binopts ], "these options cannot be used with -binary" );
1389 check_opts
( %opts, [ @txtopts ], "these options cannot be used without -binary" );
1391 if ( not exists( $opts{ -error
} ) ) {
1392 $opts{ -error
} = "error";
1394 if ( $opts{ -error
} eq "warning" ) {
1396 } elsif( $opts{ -error
} eq "ignore" ) {
1398 } elsif ( ref( $opts{ -error
} ) eq "ARRAY" ) {
1399 $error = sub { push( @
{ $opts{ -error
} }, $_[ 0 ] ); };
1402 if ( ( ref( $file ) eq "GLOB" ) or UNIVERSAL
::isa
( $file, "IO::Handle" ) ) {
1407 if ( get_ext
( $file ) eq ".gz" and not $opts{ -binary
} ) {
1408 $handle = IO
::Zlib
->new( $name, "rb" );
1410 $handle = IO
::File
->new( $name, "r" );
1412 if ( not defined( $handle ) ) {
1413 $error->( "File \"$name\" could not be opened for input: $!" );
1416 if ( defined( $handle ) ) {
1417 if ( $opts{ -binary
} ) {
1419 local $/ = undef; # Set input record separator to undef to read entire file as one line.
1420 if ( exists( $opts{ -bulk
} ) ) {
1421 ${ $opts{ -bulk
} } = $handle->getline();
1423 $bulk[ 0 ] = $handle->getline();
1426 if ( defined( $opts{ -layer
} ) ) {
1427 binmode( $handle, $opts{ -layer
} );
1429 @bulk = $handle->getlines();
1430 # Special trick for UTF-8 files: Delete BOM, if any.
1431 if ( defined( $opts{ -layer
} ) and $opts{ -layer
} eq ":utf8" ) {
1432 if ( substr( $bulk[ 0 ], 0, 1 ) eq "\x{FEFF}" ) {
1433 substr( $bulk[ 0 ], 0, 1 ) = "";
1438 or $error->( "File \"$name\" could not be closed after input: $!" );
1440 if ( $opts{ -binary
} and exists( $opts{ -bulk
} ) ) {
1441 ${ $opts{ -bulk
} } = "";
1444 if ( $opts{ -binary
} ) {
1445 if ( exists( $opts{ -bulk
} ) ) {
1451 if ( ( @bulk > 0 ) and ( substr( $bulk[ -1 ], -1, 1 ) ne "\n" ) ) {
1452 $bulk[ -1 ] .= "\n";
1454 if ( not $opts{ -keep_trailing_space
} ) {
1455 map( $_ =~ s/\s+\n\z/\n/, @bulk );
1457 if ( $opts{ -chomp } ) {
1460 if ( wantarray() ) {
1463 return join( "", @bulk );
1469 #--------------------------------------------------------------------------------------------------
1475 write_file( $file, $bulk, @options )
1487 The name or handle of file to write to.
1491 Bulk to write to a file. Can be a scalar, or a reference to scalar or an array.
1501 If true, create a backup copy of file overwritten. Backup copy is placed into the same directory.
1502 The name of backup copy is the same as the name of file with `~' appended. By default backup copy
1507 If true, the text will be added to existing file.
1513 write_file( "message.txt", \$bulk );
1514 # Write file, take content from a scalar.
1516 write_file( "message.txt", \@bulk, -backup => 1 );
1517 # Write file, take content from an array, create a backup copy.
1521 sub write_file
($$@
) {
1523 my $file = shift( @_ ); # The name or handle of file to write to.
1524 my $bulk = shift( @_ ); # The text to write. Can be reference to array or scalar.
1525 my %opts = @_; # Options.
1530 check_opts
( %opts, [ qw( -append -backup -binary -layer ) ] );
1532 my $mode = $opts{ -append
} ?
"a": "w";
1533 if ( ( ref( $file ) eq "GLOB" ) or UNIVERSAL
::isa
( $file, "IO::Handle" ) ) {
1538 if ( $opts{ -backup
} and ( -f
$name ) ) {
1539 copy_file
( $name, $name . "~", -overwrite
=> 1 );
1541 $handle = IO
::File
->new( $name, $mode )
1542 or runtime_error
( "File \"$name\" could not be opened for output: $!" );
1544 if ( $opts{ -binary
} ) {
1546 } elsif ( $opts{ -layer
} ) {
1547 binmode( $handle, $opts{ -layer
} );
1549 if ( ref( $bulk ) eq "" ) {
1550 if ( defined( $bulk ) ) {
1551 $handle->print( $bulk );
1552 if ( not $opts{ -binary
} and ( substr( $bulk, -1 ) ne "\n" ) ) {
1553 $handle->print( "\n" );
1556 } elsif ( ref( $bulk ) eq "SCALAR" ) {
1557 if ( defined( $$bulk ) ) {
1558 $handle->print( $$bulk );
1559 if ( not $opts{ -binary
} and ( substr( $$bulk, -1 ) ne "\n" ) ) {
1560 $handle->print( "\n" );
1563 } elsif ( ref( $bulk ) eq "ARRAY" ) {
1564 foreach my $line ( @
$bulk ) {
1565 if ( defined( $line ) ) {
1566 $handle->print( $line );
1567 if ( not $opts{ -binary
} and ( substr( $line, -1 ) ne "\n" ) ) {
1568 $handle->print( "\n" );
1573 Carp
::croak
( "write_file: \$bulk must be a scalar or reference to (scalar or array)" );
1576 or runtime_error
( "File \"$name\" could not be closed after output: $!" );
1580 #--------------------------------------------------------------------------------------------------
1584 # =================================================================================================
1585 # Execution subroutines.
1586 # =================================================================================================
1588 =head2 Execution subroutines.
1594 #--------------------------------------------------------------------------------------------------
1598 my $arg = shift( @_ );
1600 # If redirection is not required, exit.
1601 if ( not exists( $arg->{ redir
} ) ) {
1606 my $mode = $arg->{ mode
}; # Mode, "<" (input ) or ">" (output).
1607 my $handle = $arg->{ handle
}; # Handle to manipulate.
1608 my $redir = $arg->{ redir
}; # Data, a file name if a scalar, or file contents, if a reference.
1610 # Output parameters.
1615 # Save original handle (by duping it).
1616 $save_handle = Symbol
::gensym
();
1618 open( $save_handle, $mode . "&" . $handle->fileno() )
1619 or die( "Cannot dup filehandle: $!" );
1621 # Prepare a file to IO.
1622 if ( UNIVERSAL
::isa
( $redir, "IO::Handle" ) or ( ref( $redir ) eq "GLOB" ) ) {
1623 # $redir is reference to an object of IO::Handle class (or its decedant).
1624 $temp_handle = $redir;
1625 } elsif ( ref( $redir ) ) {
1626 # $redir is a reference to content to be read/written.
1627 # Prepare temp file.
1628 ( $temp_handle, $temp_name ) =
1629 File
::Temp
::tempfile
(
1631 DIR
=> File
::Spec
->tmpdir(),
1635 if ( not defined( $temp_handle ) ) {
1636 runtime_error
( "Could not create temp file." );
1638 if ( $mode eq "<" ) {
1639 # It is a file to be read by child, prepare file content to be read.
1640 $temp_handle->print( ref( $redir ) eq "SCALAR" ?
${ $redir } : @
{ $redir } );
1641 $temp_handle->flush();
1642 seek( $temp_handle, 0, 0 );
1643 # Unfortunatelly, I could not use OO interface to seek.
1644 # ActivePerl 5.6.1 complains on both forms:
1645 # $temp_handle->seek( 0 ); # As declared in IO::Seekable.
1646 # $temp_handle->setpos( 0 ); # As described in documentation.
1647 } elsif ( $mode eq ">" ) {
1648 # It is a file for output. Clear output variable.
1649 if ( ref( $redir ) eq "SCALAR" ) {
1656 # $redir is a name of file to be read/written.
1658 if ( defined( $redir ) ) {
1659 $temp_name = $redir;
1661 $temp_name = File
::Spec
->devnull();
1663 $temp_handle = IO
::File
->new( $temp_name, $mode )
1664 or runtime_error
( "file \"$temp_name\" could not be opened for " . ( $mode eq "<" ?
"input" : "output" ) . ": $!" );
1667 # Redirect handle to temp file.
1668 open( $handle, $mode . "&" . $temp_handle->fileno() )
1669 or die( "Cannot dup filehandle: $!" );
1671 # Save output parameters.
1672 $arg->{ save_handle
} = $save_handle;
1673 $arg->{ temp_handle
} = $temp_handle;
1674 $arg->{ temp_name
} = $temp_name;
1681 my $arg = shift( @_ );
1684 my $mode = $arg->{ mode
}; # Mode, "<" or ">".
1685 my $handle = $arg->{ handle
}; # Handle to save and set.
1686 my $redir = $arg->{ redir
}; # Data, a file name if a scalar, or file contents, if a reference.
1688 # Parameters saved during preprocessing.
1689 my $save_handle = $arg->{ save_handle
};
1690 my $temp_handle = $arg->{ temp_handle
};
1691 my $temp_name = $arg->{ temp_name
};
1693 # If no handle was saved, exit.
1694 if ( not $save_handle ) {
1702 # Read the content of temp file, if necessary, and close temp file.
1703 if ( ( $mode ne "<" ) and ref( $redir ) ) {
1704 $temp_handle->flush();
1705 seek( $temp_handle, 0, 0 );
1706 if ( $^O
=~ m/MSWin/ ) {
1707 binmode( $temp_handle, ":crlf" );
1709 if ( ref( $redir ) eq "SCALAR" ) {
1710 ${ $redir } .= join( "", $temp_handle->getlines() );
1711 } elsif ( ref( $redir ) eq "ARRAY" ) {
1712 push( @
{ $redir }, $temp_handle->getlines() );
1715 if ( not UNIVERSAL
::isa
( $redir, "IO::Handle" ) ) {
1716 $temp_handle->close()
1720 # Restore handle to original value.
1721 $save_handle->flush();
1722 open( $handle, $mode . "&" . $save_handle->fileno() )
1723 or die( "Cannot dup filehandle: $!" );
1725 # Close save handle.
1726 $save_handle->close()
1729 # Delete parameters saved during preprocessing.
1730 delete( $arg->{ save_handle
} );
1731 delete( $arg->{ temp_handle
} );
1732 delete( $arg->{ temp_name
} );
1736 #--------------------------------------------------------------------------------------------------
1738 =item C<execute( [ @command ], @options )>
1740 Execute specified program or shell command.
1742 Program is specified by reference to an array, that array is passed to C<system()> function which
1743 executes the command. See L<perlfunc> for details how C<system()> interprets various forms of
1746 By default, in case of any error error message is issued and script terminated (by runtime_error()).
1747 Function returns an exit code of program.
1749 Alternatively, he function may return exit status of the program (see C<-ignore_status>) or signal
1750 (see C<-ignore_signal>) so caller may analyze it and continue execution.
1758 Redirect stdin of program. The value of option can be:
1764 Stdin of child is attached to null device.
1768 Stdin of child is attached to a file with name specified by option.
1770 =item a reference to a scalar
1772 A dereferenced scalar is written to a temp file, and child's stdin is attached to that file.
1774 =item a reference to an array
1776 A dereferenced array is written to a temp file, and child's stdin is attached to that file.
1782 Redirect stdout. Possible values are the same as for C<-stdin> option. The only difference is
1783 reference specifies a variable receiving program's output.
1787 It similar to C<-stdout>, but redirects stderr. There is only one additional value:
1791 =item an empty string
1793 means that stderr should be redirected to the same place where stdout is redirected to.
1799 Redirected stream will not overwrite previous content of file (or variable).
1800 Note, that option affects both stdout and stderr.
1802 =item C<-ignore_status>
1804 By default, subroutine raises an error and exits the script if program returns non-exit status. If
1805 this options is true, no error is raised. Instead, status is returned as function result (and $@ is
1806 set to error message).
1808 =item C<-ignore_signal>
1810 By default, subroutine raises an error and exits the script if program die with signal. If
1811 this options is true, no error is raised in such a case. Instead, signal number is returned (as
1812 negative value), error message is placed to C<$@> variable.
1814 If command is not even started, -256 is returned.
1820 execute( [ "cmd.exe", "/c", "dir" ] );
1821 # Execute NT shell with specified options, no redirections are
1825 execute( [ "cvs", "-n", "-q", "update", "." ], -stdout => \$output );
1826 # Execute "cvs -n -q update ." command, output is saved
1827 # in $output variable.
1830 execute( [ qw( cvs -n -q update . ) ], -stdout => \@output, -stderr => undef );
1831 # Execute specified command, output is saved in @output
1832 # variable, stderr stream is redirected to null device
1833 # (/dev/null in Linux* OS and nul in Windows* OS).
1839 # !!! Add something to complain on unknown options...
1841 my $command = shift( @_ );
1843 my $prefix = "Could not execute $command->[ 0 ]";
1845 check_opts
( %opts, [ qw( -stdin -stdout -stderr -append -ignore_status -ignore_signal ) ] );
1847 if ( ref( $command ) ne "ARRAY" ) {
1848 Carp
::croak
( "execute: $command must be a reference to array" );
1851 my $stdin = { handle
=> \
*STDIN
, mode
=> "<" };
1852 my $stdout = { handle
=> \
*STDOUT
, mode
=> ">" };
1853 my $stderr = { handle
=> \
*STDERR
, mode
=> ">" };
1860 for my $stream ( qw( stdin stdout stderr ) ) {
1861 if ( exists( $opts{ "-$stream" } ) ) {
1862 if ( ref( $opts{ "-$stream" } ) !~ m/\A(|SCALAR|ARRAY)\z/ ) {
1863 Carp
::croak
( "execute: -$stream option: must have value of scalar, or reference to (scalar or array)." );
1865 $streams->{ $stream }->{ redir
} = $opts{ "-$stream" };
1867 if ( $opts{ -append
} and ( $streams->{ $stream }->{ mode
} ) eq ">" ) {
1868 $streams->{ $stream }->{ mode
} = ">>";
1870 }; # foreach $stream
1874 if ( defined( $stderr->{ redir
} ) and not ref( $stderr->{ redir
} ) and ( $stderr->{ redir
} eq "" ) ) {
1875 if ( exists( $stdout->{ redir
} ) ) {
1876 $stderr->{ redir
} = $stdout->{ temp_handle
};
1878 $stderr->{ redir
} = ${ $stdout->{ handle
} };
1882 my $rc = system( @
$command );
1890 my $signal_num = $child & 127;
1891 my $exit_status = $child >> 8;
1895 $@
= "\"$command->[ 0 ]\" failed: $errno";
1897 if ( not $opts{ -ignore_signal
} ) {
1898 runtime_error
( $@
);
1900 } elsif ( $signal_num != 0 ) {
1901 $@
= "\"$command->[ 0 ]\" failed due to signal $signal_num.";
1902 $exit = - $signal_num;
1903 if ( not $opts{ -ignore_signal
} ) {
1904 runtime_error
( $@
);
1906 } elsif ( $exit_status != 0 ) {
1907 $@
= "\"$command->[ 0 ]\" returned non-zero status $exit_status.";
1908 $exit = $exit_status;
1909 if ( not $opts{ -ignore_status
} ) {
1910 runtime_error
( $@
);
1918 #--------------------------------------------------------------------------------------------------
1920 =item C<backticks( [ @command ], @options )>
1922 Run specified program or shell command and return output.
1924 In scalar context entire output is returned in a single string. In list context list of strings
1925 is returned. Function issues an error and exits script if any error occurs.
1932 my $command = shift( @_ );
1936 check_opts
( %opts, [ qw( -chomp ) ] );
1938 execute
( $command, -stdout
=> \
@output );
1940 if ( $opts{ -chomp } ) {
1944 return ( wantarray() ?
@output : join( "", @output ) );
1948 #--------------------------------------------------------------------------------------------------
1951 my ( $str, $length, $pad ) = @_;
1952 my $lstr = length( $str ); # Length of source string.
1953 if ( $lstr < $length ) {
1954 my $lpad = length( $pad ); # Length of pad.
1955 my $count = int( ( $length - $lstr ) / $lpad ); # Number of pad repetitions.
1956 my $tail = $length - ( $lstr + $lpad * $count );
1957 $str = $str . ( $pad x
$count ) . substr( $pad, 0, $tail );
1962 # --------------------------------------------------------------------------------------------------
1968 #--------------------------------------------------------------------------------------------------
1972 #--------------------------------------------------------------------------------------------------