65 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| package Git::SVN::GlobSpec;
 | |
| use strict;
 | |
| use warnings;
 | |
| 
 | |
| sub new {
 | |
| 	my ($class, $glob, $pattern_ok) = @_;
 | |
| 	my $re = $glob;
 | |
| 	$re =~ s!/+$!!g; # no need for trailing slashes
 | |
| 	my (@left, @right, @patterns);
 | |
| 	my $state = "left";
 | |
| 	my $die_msg = "Only one set of wildcards " .
 | |
| 				"(e.g. '*' or '*/*/*') is supported: $glob\n";
 | |
| 	for my $part (split(m|/|, $glob)) {
 | |
| 		if ($pattern_ok && $part =~ /[{}]/ &&
 | |
| 			 $part !~ /^\{[^{}]+\}/) {
 | |
| 			die "Invalid pattern in '$glob': $part\n";
 | |
| 		}
 | |
| 		my $nstars = $part =~ tr/*//;
 | |
| 		if ($nstars > 1) {
 | |
| 			die "Only one '*' is allowed in a pattern: '$part'\n";
 | |
| 		}
 | |
| 		if ($part =~ /(.*)\*(.*)/) {
 | |
| 			die $die_msg if $state eq "right";
 | |
| 			my ($l, $r) = ($1, $2);
 | |
| 			$state = "pattern";
 | |
| 			my $pat = quotemeta($l) . '[^/]*' . quotemeta($r);
 | |
| 			push(@patterns, $pat);
 | |
| 		} elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
 | |
| 			die $die_msg if $state eq "right";
 | |
| 			$state = "pattern";
 | |
| 			my $p = quotemeta($1);
 | |
| 			$p =~ s/\\,/|/g;
 | |
| 			push(@patterns, "(?:$p)");
 | |
| 		} else {
 | |
| 			if ($state eq "left") {
 | |
| 				push(@left, $part);
 | |
| 			} else {
 | |
| 				push(@right, $part);
 | |
| 				$state = "right";
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	my $depth = @patterns;
 | |
| 	if ($depth == 0) {
 | |
| 		die "One '*' is needed in glob: '$glob'\n";
 | |
| 	}
 | |
| 	my $left = join('/', @left);
 | |
| 	my $right = join('/', @right);
 | |
| 	$re = join('/', @patterns);
 | |
| 	$re = join('\/',
 | |
| 		   grep(length, quotemeta($left),
 | |
|                                 "($re)(?=/|\$)",
 | |
|                                 quotemeta($right)));
 | |
| 	my $left_re = qr/^\/\Q$left\E(\/|$)/;
 | |
| 	bless { left => $left, right => $right, left_regex => $left_re,
 | |
| 	        regex => qr/$re/, glob => $glob, depth => $depth }, $class;
 | |
| }
 | |
| 
 | |
| sub full_path {
 | |
| 	my ($self, $path) = @_;
 | |
| 	return (length $self->{left} ? "$self->{left}/" : '') .
 | |
| 	       $path . (length $self->{right} ? "/$self->{right}" : '');
 | |
| }
 | |
| 
 | |
| 1;
 |