Prima

 view release on metacpan or  search on metacpan

Prima/sys/FS.pm  view on Meta::CPAN

NATIVE:
	goto &CORE::open;
}

sub opendir(*$)
{
	if ( readonly($_[0])) {
		warn "Prima::sys::FS::opendir: cannot be use on filehandles, variables only\n";
		return;
	}
	$_[0] = open_dir( $_[1] );
	return defined $_[0];
}

sub readdir($)
{
	my $dh = shift;

	if ( wantarray ) {
		my @ret;
		while ( defined( my $f = read_dir($dh)) ) {
			push @ret, $f;
		}
		return @ret;
	} else {
		return read_dir($dh);
	}
}

sub glob
{
	my $pat = shift;
	my @pats;
	while ( 1 ) {
		$pat =~ m/\G"((?:[^"]|\\")*)(?<!\\)"/gcs and push @pats, $1 and next;
		$pat =~ m/\G'((?:[^']|\\')*)(?<!\\)'/gcs and push @pats, $1 and next;
		$pat =~ m/\G((?:\S|\\\s)+)/gcs and push @pats, $1 and next;
		$pat =~ m/\G\s+/gcs and next;
		$pat =~ m/\G$/gcs and last;
	}
	my @matches = @pats;
	@pats = ();
	my $win32 = $^O =~ /win32/i;
	MATCH: while ( my $q = shift @matches ) {
		if ( $q =~ m/^(.*)\{([^}]*)\}(.*)$/ ) {
			my ( $pre, $subpat, $post ) = ( $1, $2, $3 );
			push @matches, map { "$pre$_$post" } split /,/, $subpat;
		} elsif ( $q =~ m/^(.*)\[([^\]]*)\](.*)$/ ) {
			my ( $pre, $subpat, $post ) = ( $1, $2, $3 );
			push @matches, map { "$pre$_$post" } split //, $subpat;
		} elsif ( $q =~ m/^~(\w*)(.*)/ ) {
			my @pwent;
			unless ( length $1 ) {
				push @matches, ($ENV{HOME} // ($win32 ? $ENV{USERPROFILE} : undef) // '/' ) . $2;
			} elsif (!$win32 && (@pwent = getpwnam($1)) && defined($pwent[7])) {
				push @matches, $pwent[7] .  $2;
			}
		} elsif ( $q =~ m/(?<!\\)\*|\?/ ) {
			my @paths = ('');
			my $expanded;
			for my $subpath ( split m{(/)}, $q ) {
				if ( !$expanded && $subpath =~ m/(?<!\\)\*|\?/ ) {
					$subpath =~ s/(?<!\\)\*/.*/g;
					$subpath =~ s/(?<!\\)\?/./g;
					$subpath = qr/$subpath/;
					next MATCH unless Prima::sys::FS::opendir( my $dh, length($paths[0]) ? $paths[0] : '.' );
					my $opath = pop @paths;
					for my $e ( Prima::sys::FS::readdir $dh ) {
						next unless $e =~ /^$subpath$/;
						push @paths, $opath . $e;
					}
					Prima::Utils::closedir $dh;
					$expanded++;
				} else {
					$_ .= $subpath for @paths;
				}
			}
			push @matches, @paths;
		} elsif (_e($q)) {
			push @pats, $q;
		}
	}

	return @pats;
}

sub lstat { Prima::Utils::stat($_[0], 1) }

sub __x(&$) {
	my @p = Prima::Utils::stat($_[1]);
	return undef unless scalar @p;
	$_[0]->(@p);
}

sub __f($$) {
	no strict 'refs';
	my @p = Prima::Utils::stat($_[1]);
	return undef unless scalar @p;
	return undef unless ${'Fcntl::'}{$_[0]};
	my $c = Fcntl->can($_[0])->();
	return (($c & $p[2]) == $c) ? 1 : 0;
}

sub _l ($) {
	no strict 'refs';
	my @p = Prima::Utils::stat($_[1], 1);
	return undef unless scalar @p;
	return undef unless ${'Fcntl::'}{S_IFLNK};
	my $c = Fcntl->can('S_IFLNK')->();
	return (($c & $p[2]) == $c) ? 1 : 0;
}

sub _r ($) { access($_[0], 4, 1) >= 0 }
sub _w ($) { access($_[0], 2, 1) >= 0 }
sub _x ($) { access($_[0], 1, 1) >= 0 }
sub _o ($) { __x sub { $> == $_[4] }, $_[0] }
sub _R ($) { access($_[0], 4, 0) >= 0 }
sub _W ($) { access($_[0], 2, 0) >= 0 }
sub _X ($) { access($_[0], 1, 0) >= 0 }
sub _O ($) { __x sub { $< == $_[4] }, $_[0] }
sub _e ($) { __x sub { 1 }, $_[0] }



( run in 1.237 second using v1.01-cache-2.11-cpan-71847e10f99 )