@@ -12,50 +12,140 @@ License: perl
1212
1313=cut
1414
15+ package PerlPowerTools::glob ;
16+
17+ use strict;
18+ use warnings;
19+
1520our $VERSION = ' 2.1' ;
1621
1722use constant EX_SUCCESS => 0;
1823use constant EX_FAILURE => 1;
24+ use constant EX_ERROR => 2;
1925
20- use File::Glob qw( csh_glob) ;
26+ use File::Basename;
27+ use File::Glob qw( csh_glob GLOB_CSH) ;
2128
22- my $separator = " \n " ;
23- if ( $ARGV [0] eq ' -0' ) {
24- shift @ARGV ;
25- $separator = " \0 " ;
26- }
29+ __PACKAGE__ -> run(@ARGV ) unless caller ();
30+
31+ my %Unknown_users ;
32+ my $wildcards = qr / [*?\[ ]/ ;
33+
34+ sub run {
35+ my ( $class , @args ) = @_ ;
2736
28- my $pattern = " @ARGV " ;
37+ my ( $code , $message ) = do {
38+ if ( @args == 0 ) {
39+ ( EX_ERROR, undef );
40+ }
41+ else {
42+ my $separator = " \n " ;
43+ if ( $args [0] eq ' -0' ) {
44+ shift @args ;
45+ $separator = " \0 " ;
46+ }
47+
48+ my @ARGV_expanded = @args ;
49+ if ( $^O =~ / \A MSWin32 \z /x ) {
50+ @ARGV_expanded = map { expand_tilde($_ ) } @ARGV_expanded ;
51+ }
52+
53+ my @matches = csh_glob( " @ARGV_expanded " , GLOB_CSH );
54+
55+ if ( @matches ) {
56+ $class -> output_list( \@matches , $separator );
57+ ( EX_SUCCESS );
58+ }
59+ elsif ( () = keys %Unknown_users ) {
60+ ( EX_FAILURE, $class -> no_match_message );
61+ }
62+ else {
63+ my $message = do {
64+ my $pattern = " @args " ;
65+ my $unknown = () = keys %Unknown_users ;
66+
67+ if ( $^O ne ' MSWin32' && $pattern =~ / (?:\A |\s )~([\w -]+?)\b / ) {
68+ getpwnam ($u ) ? undef : " Unknown user $1 ." ;
69+ }
70+ elsif ( $pattern =~ $wildcards ) {
71+ ( EX_FAILURE, $class -> no_match_message );
72+ }
73+ else { undef }
74+ };
75+
76+ ( EX_FAILURE, $message );
77+ }
78+ }
79+ };
2980
30- my @matches = csh_glob( $pattern );
81+ $class -> exit( $code , $message );
82+ }
3183
32- if ( @matches ) {
33- print join $separator , @matches ;
34- exit EX_SUCCESS;
84+ sub exit {
85+ my ( $class , $code , $message ) = @_ ;
86+
87+ print STDERR $message if defined $message ;
88+ exit ( $code // 0 );
3589 }
3690
37- my $message = do {
38- if ( $pattern =~ / (?: \A | \s )~([ \w -]+?) \b / ) {
39- my $u = $1 ;
40- my $m = " Unknown user $u . " ;
91+ sub expand_tilde {
92+ return $_ [0] unless $^O eq ' MSWin32 ' ;
93+ return $_ [0] unless $_ [0] =~ $wildcards ;
94+ local $_ = $_ [0] ;
4195
42- if ( $^O =~ / \A MSWin32 \z /x ) {
43- local $_ = ` net user $u ` ;
44- / could not be found|The syntax of this command/ ? $m : ();
45- }
46- elsif ( ! getpwnam ($u ) ) {
47- $m
96+ my $home = my_home();
97+ my $dir = dirname($home ) // ' /Users' ;
98+
99+ return unless m / \A ~ (\w +)? / x ;
100+ my $user = $1 ;
101+
102+ if ( $user && ! $Unknown_users {$user } ) {
103+ my $net_user = ` net user "$user " 2>&1` ;
104+ if ( $net_user =~ / could not be found|The syntax of this command/ ) {
105+ print STDERR " Unknown user $user .\n " ;
106+ $Unknown_users {$user }++;
107+ return ;
48108 }
49- else { undef }
109+ s / \A ~ ( \w +) / $dir \\ $1 / x
50110 }
51- elsif ( $pattern =~ / [*? \[ ] / ) {
52- " No Match " ;
111+ else {
112+ s / \A ~ / $home / x ;
53113 }
54- else { undef }
55- };
56114
57- print STDERR $message if defined $message ;
58- exit EX_FAILURE;
115+ return $_ ;
116+ }
117+
118+ # Stolen from File::HomeDir::Windows;
119+ sub my_home {
120+ # A lot of unix people and unix-derived tools rely on
121+ # the ability to overload HOME. We will support it too
122+ # so that they can replace raw HOME calls with File::HomeDir.
123+ if (exists $ENV {HOME } and defined $ENV {HOME } and length $ENV {HOME }) {
124+ return $ENV {HOME };
125+ }
126+
127+ # Do we have a user profile?
128+ if (exists $ENV {USERPROFILE } and $ENV {USERPROFILE }) {
129+ return $ENV {USERPROFILE };
130+ }
131+
132+ # Some Windows use something like $ENV{HOME}
133+ if (exists $ENV {HOMEDRIVE } and exists $ENV {HOMEPATH } and $ENV {HOMEDRIVE } and $ENV {HOMEPATH }) {
134+ return File::Spec-> catpath($ENV {HOMEDRIVE }, $ENV {HOMEPATH }, ' ' ,);
135+ }
136+
137+ return ;
138+ }
139+
140+ sub output_list {
141+ my ( $class , $array , $separator ) = @_ ;
142+ $separator = " \n " unless defined $separator ;
143+
144+ print STDOUT join $separator , @$array ;
145+ print " \n " ;
146+ }
147+
148+ =encoding utf8
59149
60150=head1 NAME
61151
0 commit comments