xref: /openbsd-src/gnu/usr.bin/perl/cpan/ExtUtils-MakeMaker/lib/ExtUtils/Command.pm (revision e068048151d29f2562a32185e21a8ba885482260)
1b8851fccSafresh1package ExtUtils::Command;
2b8851fccSafresh1
3b8851fccSafresh1use 5.00503;
4b8851fccSafresh1use strict;
5eac174f2Safresh1use warnings;
6b8851fccSafresh1require Exporter;
7*e0680481Safresh1our @ISA     = qw(Exporter);
8*e0680481Safresh1our @EXPORT  = qw(cp rm_f rm_rf mv cat eqtime mkpath touch test_f test_d chmod
9b8851fccSafresh1                  dos2unix);
10*e0680481Safresh1our $VERSION = '7.70';
1156d68f1eSafresh1$VERSION =~ tr/_//d;
12b8851fccSafresh1
13b8851fccSafresh1my $Is_VMS   = $^O eq 'VMS';
14b8851fccSafresh1my $Is_VMS_mode = $Is_VMS;
15b8851fccSafresh1my $Is_VMS_noefs = $Is_VMS;
16b8851fccSafresh1my $Is_Win32 = $^O eq 'MSWin32';
17b8851fccSafresh1
18b8851fccSafresh1if( $Is_VMS ) {
19b8851fccSafresh1    my $vms_unix_rpt;
20b8851fccSafresh1    my $vms_efs;
21b8851fccSafresh1    my $vms_case;
22b8851fccSafresh1
23b8851fccSafresh1    if (eval { local $SIG{__DIE__};
24b8851fccSafresh1               local @INC = @INC;
25b8851fccSafresh1               pop @INC if $INC[-1] eq '.';
26b8851fccSafresh1               require VMS::Feature; }) {
27b8851fccSafresh1        $vms_unix_rpt = VMS::Feature::current("filename_unix_report");
28b8851fccSafresh1        $vms_efs = VMS::Feature::current("efs_charset");
29b8851fccSafresh1        $vms_case = VMS::Feature::current("efs_case_preserve");
30b8851fccSafresh1    } else {
31b8851fccSafresh1        my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
32b8851fccSafresh1        my $efs_charset = $ENV{'DECC$EFS_CHARSET'} || '';
33b8851fccSafresh1        my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || '';
34b8851fccSafresh1        $vms_unix_rpt = $unix_rpt =~ /^[ET1]/i;
35b8851fccSafresh1        $vms_efs = $efs_charset =~ /^[ET1]/i;
36b8851fccSafresh1        $vms_case = $efs_case =~ /^[ET1]/i;
37b8851fccSafresh1    }
38b8851fccSafresh1    $Is_VMS_mode = 0 if $vms_unix_rpt;
39b8851fccSafresh1    $Is_VMS_noefs = 0 if ($vms_efs);
40b8851fccSafresh1}
41b8851fccSafresh1
42b8851fccSafresh1
43b8851fccSafresh1=head1 NAME
44b8851fccSafresh1
45b8851fccSafresh1ExtUtils::Command - utilities to replace common UNIX commands in Makefiles etc.
46b8851fccSafresh1
47b8851fccSafresh1=head1 SYNOPSIS
48b8851fccSafresh1
49b8851fccSafresh1  perl -MExtUtils::Command -e cat files... > destination
50b8851fccSafresh1  perl -MExtUtils::Command -e mv source... destination
51b8851fccSafresh1  perl -MExtUtils::Command -e cp source... destination
52b8851fccSafresh1  perl -MExtUtils::Command -e touch files...
53b8851fccSafresh1  perl -MExtUtils::Command -e rm_f files...
54b8851fccSafresh1  perl -MExtUtils::Command -e rm_rf directories...
55b8851fccSafresh1  perl -MExtUtils::Command -e mkpath directories...
56b8851fccSafresh1  perl -MExtUtils::Command -e eqtime source destination
57b8851fccSafresh1  perl -MExtUtils::Command -e test_f file
58b8851fccSafresh1  perl -MExtUtils::Command -e test_d directory
59b8851fccSafresh1  perl -MExtUtils::Command -e chmod mode files...
60b8851fccSafresh1  ...
61b8851fccSafresh1
62b8851fccSafresh1=head1 DESCRIPTION
63b8851fccSafresh1
64b8851fccSafresh1The module is used to replace common UNIX commands.  In all cases the
65b8851fccSafresh1functions work from @ARGV rather than taking arguments.  This makes
66b8851fccSafresh1them easier to deal with in Makefiles.  Call them like this:
67b8851fccSafresh1
68b8851fccSafresh1  perl -MExtUtils::Command -e some_command some files to work on
69b8851fccSafresh1
70b8851fccSafresh1and I<NOT> like this:
71b8851fccSafresh1
72b8851fccSafresh1  perl -MExtUtils::Command -e 'some_command qw(some files to work on)'
73b8851fccSafresh1
74b8851fccSafresh1For that use L<Shell::Command>.
75b8851fccSafresh1
76b8851fccSafresh1Filenames with * and ? will be glob expanded.
77b8851fccSafresh1
78b8851fccSafresh1
79b8851fccSafresh1=head2 FUNCTIONS
80b8851fccSafresh1
81b8851fccSafresh1=over 4
82b8851fccSafresh1
83b8851fccSafresh1=cut
84b8851fccSafresh1
85b8851fccSafresh1# VMS uses % instead of ? to mean "one character"
86b8851fccSafresh1my $wild_regex = $Is_VMS ? '*%' : '*?';
87b8851fccSafresh1sub expand_wildcards
88b8851fccSafresh1{
89b8851fccSafresh1 @ARGV = map(/[$wild_regex]/o ? glob($_) : $_,@ARGV);
90b8851fccSafresh1}
91b8851fccSafresh1
92b8851fccSafresh1
93b8851fccSafresh1=item cat
94b8851fccSafresh1
95b8851fccSafresh1    cat file ...
96b8851fccSafresh1
97b8851fccSafresh1Concatenates all files mentioned on command line to STDOUT.
98b8851fccSafresh1
99b8851fccSafresh1=cut
100b8851fccSafresh1
101b8851fccSafresh1sub cat ()
102b8851fccSafresh1{
103b8851fccSafresh1 expand_wildcards();
104b8851fccSafresh1 print while (<>);
105b8851fccSafresh1}
106b8851fccSafresh1
107b8851fccSafresh1=item eqtime
108b8851fccSafresh1
109b8851fccSafresh1    eqtime source destination
110b8851fccSafresh1
111b8851fccSafresh1Sets modified time of destination to that of source.
112b8851fccSafresh1
113b8851fccSafresh1=cut
114b8851fccSafresh1
115b8851fccSafresh1sub eqtime
116b8851fccSafresh1{
117b8851fccSafresh1 my ($src,$dst) = @ARGV;
118b8851fccSafresh1 local @ARGV = ($dst);  touch();  # in case $dst doesn't exist
119b8851fccSafresh1 utime((stat($src))[8,9],$dst);
120b8851fccSafresh1}
121b8851fccSafresh1
122b8851fccSafresh1=item rm_rf
123b8851fccSafresh1
124b8851fccSafresh1    rm_rf files or directories ...
125b8851fccSafresh1
126b8851fccSafresh1Removes files and directories - recursively (even if readonly)
127b8851fccSafresh1
128b8851fccSafresh1=cut
129b8851fccSafresh1
130b8851fccSafresh1sub rm_rf
131b8851fccSafresh1{
132b8851fccSafresh1 expand_wildcards();
133b8851fccSafresh1 require File::Path;
134b8851fccSafresh1 File::Path::rmtree([grep -e $_,@ARGV],0,0);
135b8851fccSafresh1}
136b8851fccSafresh1
137b8851fccSafresh1=item rm_f
138b8851fccSafresh1
139b8851fccSafresh1    rm_f file ...
140b8851fccSafresh1
141b8851fccSafresh1Removes files (even if readonly)
142b8851fccSafresh1
143b8851fccSafresh1=cut
144b8851fccSafresh1
145b8851fccSafresh1sub rm_f {
146b8851fccSafresh1    expand_wildcards();
147b8851fccSafresh1
148b8851fccSafresh1    foreach my $file (@ARGV) {
149b8851fccSafresh1        next unless -f $file;
150b8851fccSafresh1
151b8851fccSafresh1        next if _unlink($file);
152b8851fccSafresh1
153b8851fccSafresh1        chmod(0777, $file);
154b8851fccSafresh1
155b8851fccSafresh1        next if _unlink($file);
156b8851fccSafresh1
157b8851fccSafresh1        require Carp;
158b8851fccSafresh1        Carp::carp("Cannot delete $file: $!");
159b8851fccSafresh1    }
160b8851fccSafresh1}
161b8851fccSafresh1
162b8851fccSafresh1sub _unlink {
163b8851fccSafresh1    my $files_unlinked = 0;
164b8851fccSafresh1    foreach my $file (@_) {
165b8851fccSafresh1        my $delete_count = 0;
166b8851fccSafresh1        $delete_count++ while unlink $file;
167b8851fccSafresh1        $files_unlinked++ if $delete_count;
168b8851fccSafresh1    }
169b8851fccSafresh1    return $files_unlinked;
170b8851fccSafresh1}
171b8851fccSafresh1
172b8851fccSafresh1
173b8851fccSafresh1=item touch
174b8851fccSafresh1
175b8851fccSafresh1    touch file ...
176b8851fccSafresh1
177b8851fccSafresh1Makes files exist, with current timestamp
178b8851fccSafresh1
179b8851fccSafresh1=cut
180b8851fccSafresh1
181b8851fccSafresh1sub touch {
182b8851fccSafresh1    my $t    = time;
183b8851fccSafresh1    expand_wildcards();
184b8851fccSafresh1    foreach my $file (@ARGV) {
185b8851fccSafresh1        open(FILE,">>$file") || die "Cannot write $file:$!";
186b8851fccSafresh1        close(FILE);
187b8851fccSafresh1        utime($t,$t,$file);
188b8851fccSafresh1    }
189b8851fccSafresh1}
190b8851fccSafresh1
191b8851fccSafresh1=item mv
192b8851fccSafresh1
193b8851fccSafresh1    mv source_file destination_file
194b8851fccSafresh1    mv source_file source_file destination_dir
195b8851fccSafresh1
196b8851fccSafresh1Moves source to destination.  Multiple sources are allowed if
197b8851fccSafresh1destination is an existing directory.
198b8851fccSafresh1
199b8851fccSafresh1Returns true if all moves succeeded, false otherwise.
200b8851fccSafresh1
201b8851fccSafresh1=cut
202b8851fccSafresh1
203b8851fccSafresh1sub mv {
204b8851fccSafresh1    expand_wildcards();
205b8851fccSafresh1    my @src = @ARGV;
206b8851fccSafresh1    my $dst = pop @src;
207b8851fccSafresh1
208b8851fccSafresh1    if (@src > 1 && ! -d $dst) {
209b8851fccSafresh1        require Carp;
210b8851fccSafresh1        Carp::croak("Too many arguments");
211b8851fccSafresh1    }
212b8851fccSafresh1
213b8851fccSafresh1    require File::Copy;
214b8851fccSafresh1    my $nok = 0;
215b8851fccSafresh1    foreach my $src (@src) {
216b8851fccSafresh1        $nok ||= !File::Copy::move($src,$dst);
217b8851fccSafresh1    }
218b8851fccSafresh1    return !$nok;
219b8851fccSafresh1}
220b8851fccSafresh1
221b8851fccSafresh1=item cp
222b8851fccSafresh1
223b8851fccSafresh1    cp source_file destination_file
224b8851fccSafresh1    cp source_file source_file destination_dir
225b8851fccSafresh1
226b8851fccSafresh1Copies sources to the destination.  Multiple sources are allowed if
227b8851fccSafresh1destination is an existing directory.
228b8851fccSafresh1
229b8851fccSafresh1Returns true if all copies succeeded, false otherwise.
230b8851fccSafresh1
231b8851fccSafresh1=cut
232b8851fccSafresh1
233b8851fccSafresh1sub cp {
234b8851fccSafresh1    expand_wildcards();
235b8851fccSafresh1    my @src = @ARGV;
236b8851fccSafresh1    my $dst = pop @src;
237b8851fccSafresh1
238b8851fccSafresh1    if (@src > 1 && ! -d $dst) {
239b8851fccSafresh1        require Carp;
240b8851fccSafresh1        Carp::croak("Too many arguments");
241b8851fccSafresh1    }
242b8851fccSafresh1
243b8851fccSafresh1    require File::Copy;
244b8851fccSafresh1    my $nok = 0;
245b8851fccSafresh1    foreach my $src (@src) {
246b8851fccSafresh1        $nok ||= !File::Copy::copy($src,$dst);
247b8851fccSafresh1
248b8851fccSafresh1        # Win32 does not update the mod time of a copied file, just the
249b8851fccSafresh1        # created time which make does not look at.
250b8851fccSafresh1        utime(time, time, $dst) if $Is_Win32;
251b8851fccSafresh1    }
252b8851fccSafresh1    return $nok;
253b8851fccSafresh1}
254b8851fccSafresh1
255b8851fccSafresh1=item chmod
256b8851fccSafresh1
257b8851fccSafresh1    chmod mode files ...
258b8851fccSafresh1
259b8851fccSafresh1Sets UNIX like permissions 'mode' on all the files.  e.g. 0666
260b8851fccSafresh1
261b8851fccSafresh1=cut
262b8851fccSafresh1
263b8851fccSafresh1sub chmod {
264b8851fccSafresh1    local @ARGV = @ARGV;
265b8851fccSafresh1    my $mode = shift(@ARGV);
266b8851fccSafresh1    expand_wildcards();
267b8851fccSafresh1
268b8851fccSafresh1    if( $Is_VMS_mode && $Is_VMS_noefs) {
269b8851fccSafresh1        require File::Spec;
270b8851fccSafresh1        foreach my $idx (0..$#ARGV) {
271b8851fccSafresh1            my $path = $ARGV[$idx];
272b8851fccSafresh1            next unless -d $path;
273b8851fccSafresh1
274b8851fccSafresh1            # chmod 0777, [.foo.bar] doesn't work on VMS, you have to do
275b8851fccSafresh1            # chmod 0777, [.foo]bar.dir
276b8851fccSafresh1            my @dirs = File::Spec->splitdir( $path );
277b8851fccSafresh1            $dirs[-1] .= '.dir';
278b8851fccSafresh1            $path = File::Spec->catfile(@dirs);
279b8851fccSafresh1
280b8851fccSafresh1            $ARGV[$idx] = $path;
281b8851fccSafresh1        }
282b8851fccSafresh1    }
283b8851fccSafresh1
284b8851fccSafresh1    chmod(oct $mode,@ARGV) || die "Cannot chmod ".join(' ',$mode,@ARGV).":$!";
285b8851fccSafresh1}
286b8851fccSafresh1
287b8851fccSafresh1=item mkpath
288b8851fccSafresh1
289b8851fccSafresh1    mkpath directory ...
290b8851fccSafresh1
291b8851fccSafresh1Creates directories, including any parent directories.
292b8851fccSafresh1
293b8851fccSafresh1=cut
294b8851fccSafresh1
295b8851fccSafresh1sub mkpath
296b8851fccSafresh1{
297b8851fccSafresh1 expand_wildcards();
298b8851fccSafresh1 require File::Path;
299b8851fccSafresh1 File::Path::mkpath([@ARGV],0,0777);
300b8851fccSafresh1}
301b8851fccSafresh1
302b8851fccSafresh1=item test_f
303b8851fccSafresh1
304b8851fccSafresh1    test_f file
305b8851fccSafresh1
306b8851fccSafresh1Tests if a file exists.  I<Exits> with 0 if it does, 1 if it does not (ie.
307b8851fccSafresh1shell's idea of true and false).
308b8851fccSafresh1
309b8851fccSafresh1=cut
310b8851fccSafresh1
311b8851fccSafresh1sub test_f
312b8851fccSafresh1{
313b8851fccSafresh1 exit(-f $ARGV[0] ? 0 : 1);
314b8851fccSafresh1}
315b8851fccSafresh1
316b8851fccSafresh1=item test_d
317b8851fccSafresh1
318b8851fccSafresh1    test_d directory
319b8851fccSafresh1
320b8851fccSafresh1Tests if a directory exists.  I<Exits> with 0 if it does, 1 if it does
321b8851fccSafresh1not (ie. shell's idea of true and false).
322b8851fccSafresh1
323b8851fccSafresh1=cut
324b8851fccSafresh1
325b8851fccSafresh1sub test_d
326b8851fccSafresh1{
327b8851fccSafresh1 exit(-d $ARGV[0] ? 0 : 1);
328b8851fccSafresh1}
329b8851fccSafresh1
330b8851fccSafresh1=item dos2unix
331b8851fccSafresh1
332b8851fccSafresh1    dos2unix files or dirs ...
333b8851fccSafresh1
334b8851fccSafresh1Converts DOS and OS/2 linefeeds to Unix style recursively.
335b8851fccSafresh1
336b8851fccSafresh1=cut
337b8851fccSafresh1
338b8851fccSafresh1sub dos2unix {
339b8851fccSafresh1    require File::Find;
340b8851fccSafresh1    File::Find::find(sub {
341b8851fccSafresh1        return if -d;
342b8851fccSafresh1        return unless -w _;
343b8851fccSafresh1        return unless -r _;
344b8851fccSafresh1        return if -B _;
345b8851fccSafresh1
346b8851fccSafresh1        local $\;
347b8851fccSafresh1
348b8851fccSafresh1	my $orig = $_;
349b8851fccSafresh1	my $temp = '.dos2unix_tmp';
350b8851fccSafresh1	open ORIG, $_ or do { warn "dos2unix can't open $_: $!"; return };
351b8851fccSafresh1	open TEMP, ">$temp" or
352b8851fccSafresh1	    do { warn "dos2unix can't create .dos2unix_tmp: $!"; return };
3535759b3d2Safresh1        binmode ORIG; binmode TEMP;
354b8851fccSafresh1        while (my $line = <ORIG>) {
355b8851fccSafresh1            $line =~ s/\015\012/\012/g;
356b8851fccSafresh1            print TEMP $line;
357b8851fccSafresh1        }
358b8851fccSafresh1	close ORIG;
359b8851fccSafresh1	close TEMP;
360b8851fccSafresh1	rename $temp, $orig;
361b8851fccSafresh1
362b8851fccSafresh1    }, @ARGV);
363b8851fccSafresh1}
364b8851fccSafresh1
365b8851fccSafresh1=back
366b8851fccSafresh1
367b8851fccSafresh1=head1 SEE ALSO
368b8851fccSafresh1
369b8851fccSafresh1Shell::Command which is these same functions but take arguments normally.
370b8851fccSafresh1
371b8851fccSafresh1
372b8851fccSafresh1=head1 AUTHOR
373b8851fccSafresh1
374b8851fccSafresh1Nick Ing-Simmons C<ni-s@cpan.org>
375b8851fccSafresh1
376b8851fccSafresh1Maintained by Michael G Schwern C<schwern@pobox.com> within the
377b8851fccSafresh1ExtUtils-MakeMaker package and, as a separate CPAN package, by
378b8851fccSafresh1Randy Kobes C<r.kobes@uwinnipeg.ca>.
379b8851fccSafresh1
380b8851fccSafresh1=cut
381b8851fccSafresh1
382