sub readdeps {
my ($config, $pkgidp, @depfiles) = @_;
- my %provides = ();
+ my %rprovides = ();
my %requires = ();
local *F;
- my %prov;
+ my %provides;
for my $depfile (@depfiles) {
if (ref($depfile) eq 'HASH') {
for my $rr (keys %$depfile) {
- $prov{$rr} = $depfile->{$rr}->{'provides'};
+ $provides{$rr} = $depfile->{$rr}->{'provides'};
$requires{$rr} = $depfile->{$rr}->{'requires'};
}
next;
}
push @ss, shift @s;
if (@s && $s[0] =~ /^[<=>]/) {
+ $ss[-1] .= " $s[0] $s[1]";
shift @s;
shift @s;
}
if ($s =~ s/^P:(.*):$/$1/) {
my $pkgid = $s;
$s =~ s/-[^-]+-[^-]+-[^-]+$//;
- $prov{$s} = \@ss;
+ $provides{$s} = \@ss;
$pkgidp->{$s} = $pkgid if $pkgidp;
} elsif ($s =~ s/^R:(.*):$/$1/) {
my $pkgid = $s;
}
close F;
}
- for my $p (keys %prov) {
- push @{$provides{$_}}, $p for unify(@{$prov{$p}});
- }
- my @ors = grep {/\|/} map {@$_} values %requires;
- @ors = unify(@ors) if @ors > 1;
- for my $or (@ors) {
- my @p = map {@{$provides{$_} || []}} split(/\|/, $or);
- @p = unify(@p) if @p > 1;
- $provides{$or} = \@p;
+ for my $p (keys %provides) {
+ my @pp = @{$provides{$p}};
+ s/[ <=>].*// for @pp;
+ push @{$rprovides{$_}}, $p for unify(@pp);
}
$config->{'providesh'} = \%provides;
+ $config->{'rprovidesh'} = \%rprovides;
$config->{'requiresh'} = \%requires;
}
sub forgetdeps {
my $config;
delete $config->{'providesh'};
+ delete $config->{'rprovidesh'};
delete $config->{'requiresh'};
}
+my %addproviders_fm = (
+ '>' => 1,
+ '=' => 2,
+ '>=' => 3,
+ '<' => 4,
+ '<=' => 6,
+);
+
+sub addproviders {
+ my ($config, $r) = @_;
+
+ my @p;
+ my $rprovides = $config->{'rprovidesh'};
+ $rprovides->{$r} = \@p;
+ if ($r =~ /\|/) {
+ for my $or (split(/\s*\|\s*/, $r)) {
+ push @p, @{$rprovides->{$or} || addproviders($config, $or)};
+ }
+ @p = unify(@p) if @p > 1;
+ return \@p;
+ }
+ return \@p if $r !~ /^(.*?)\s*([<=>]{1,2})\s*(.*?)$/;
+ my $rn = $1;
+ my $rv = $3;
+ my $rf = $addproviders_fm{$2};
+ return \@p unless $rf;
+ my $provides = $config->{'providesh'};
+ my @rp = @{$rprovides->{$rn} || []};
+ for my $rp (@rp) {
+ for my $pp (@{$provides->{$rp} || []}) {
+ if ($pp eq $rn) {
+ push @p, $rp;
+ last;
+ }
+ next unless $pp =~ /^\Q$rn\E\s*([<=>]{1,2})\s*(.*?)$/;
+ my $pv = $2;
+ my $pf = $addproviders_fm{$1};
+ next unless $pf;
+ if ($pf & $rf & 5) {
+ push @p, $rp;
+ last;
+ }
+ my $rr = $rf == 2 ? $pf : ($rf ^ 5);
+ $rr &= 5 unless $pf & 2;
+ my $vv = Build::Rpm::verscmp($pv, $rv, 1);
+ if ($rr & (1 << ($vv + 1))) {
+ push @p, $rp;
+ last;
+ }
+ }
+ }
+ @p = unify(@p) if @p > 1;
+ return \@p;
+}
+
sub expand {
my ($config, @p) = @_;
my $prefer = $config->{'preferh'};
my $ignore = $config->{'ignoreh'};
- my $provides = $config->{'providesh'};
+ my $rprovides = $config->{'rprovidesh'};
my $requires = $config->{'requiresh'};
my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p;
my @rerror = ();
for my $p (splice @p) {
for my $r (@{$requires->{$p} || [$p]}) {
- next if $ignore->{"$p:$r"} || $xignore{"$p:$r"};
- next if $ignore->{$r} || $xignore{$r};
- my @q = @{$provides->{$r} || []};
+ my $ri = (split(/[ <=>]/, $r, 2))[0];
+ next if $ignore->{"$p:$ri"} || $xignore{"$p:$ri"};
+ next if $ignore->{$ri} || $xignore{$ri};
+ my @q = @{$rprovides->{$r} || addproviders($config, $r)};
next if grep {$p{$_}} @q;
next if grep {$xignore{$_}} @q;
next if grep {$ignore->{"$p:$_"} || $xignore{"$p:$_"}} @q;
if (@q > 1 && $r =~ /\|/) {
# choice op, implicit prefer of first match...
my %pq = map {$_ => 1} @q;
- for my $rr (split(/\|/, $r)) {
- next unless $provides->{$rr};
- my @pq = grep {$pq{$_}} @{$provides->{$rr}};
+ for my $rr (split(/\s*\|\s*/, $r)) {
+ next unless $rprovides->{$rr};
+ my @pq = grep {$pq{$_}} @{$rprovides->{$rr}};
next unless @pq;
@q = @pq;
last;
sub add_all_providers {
my ($config, @p) = @_;
- my $provides = $config->{'providesh'};
+ my $rprovides = $config->{'rprovidesh'};
my $requires = $config->{'requiresh'};
my %a;
for my $p (@p) {
for my $r (@{$requires->{$p} || [$p]}) {
- $a{$_} = 1 for @{$provides->{$r} || []};
+ my $rn = (split(' ', $r, 2))[0];
+ $a{$_} = 1 for @{$rprovides->{$rn} || []};
}
}
push @p, keys %a;
my $src = $name;
$src = $res{'SOURCE'} if $res{'SOURCE'};
my @provides = split(',\s*', $res{'PROVIDES'} || '');
- s/\s.*// for @provides; #for now
- push @provides, $name unless grep {$_ eq $name} @provides;
+ push @provides, "$name = $res{'VERSION'}" unless grep {/^\Q$name\E(?: |$)/} @provides;
my @depends = split(',\s*', $res{'DEPENDS'} || '');
my @predepends = split(',\s*', $res{'PRE-DEPENDS'} || '');
push @depends, @predepends;
- s/\s.*// for @provides; #for now
- s/\|\s*/\|/g for @depends; #for now
- s/\s[^\|]*//g for @depends; #for now
+ s/ \(([^\)]*)\)/ $1/g for @provides;
+ s/ \(([^\)]*)\)/ $1/g for @depends;
+ s/>>/>/g for @provides;
+ s/<</</g for @provides;
+ s/>>/>/g for @depends;
+ s/<</</g for @depends;
my $data = {
name => $name,
hdrmd5 => $res{'CONTROL_MD5'},
return %res;
}
-sub rpmq_add_flagsvers {
+sub add_flagsvers {
my $res = shift;
my $name = shift;
my $flags = shift;
return -1 if $x1 eq '' || $x2 eq '';
$r = $x1 cmp $x2;
}
- return $r if $r;
+ return $r > 0 ? 1 : -1 if $r;
if ($s1 eq '') {
return $s2 eq '' ? 0 : -1;
}
}
sub verscmp {
- my ($s1, $s2) = @_;
+ my ($s1, $s2, $dtest) = @_;
return 0 if $s1 eq $s2;
my ($e1, $v1, $r1) = $s1 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$e1 = 0 unless defined $e1;
- $r1 = '' unless defined $r1;
my ($e2, $v2, $r2) = $s2 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$e2 = 0 unless defined $e2;
- $r2 = '' unless defined $r2;
if ($e1 ne $e2) {
my $r = verscmp_part($e1, $e2);
return $r if $r;
}
+ return 0 if $dtest && ($v1 eq '' || $v2 eq '');
if ($v1 ne $v2) {
my $r = verscmp_part($v1, $v2);
return $r if $r;
}
+ $r1 = '' unless defined $r1;
+ $r2 = '' unless defined $r2;
+ return 0 if $dtest && ($r1 eq '' || $r2 eq '');
if ($r1 ne $r2) {
return verscmp_part($r1, $r2);
}
my $src = $res{'SOURCERPM'}->[0];
$src = '' unless defined $src;
$src =~ s/-[^-]*-[^-]*\.[^\.]*\.rpm//;
+ add_flagsvers(\%res, 'PROVIDENAME', 'PROVIDEFLAGS', 'PROVIDEVERSION');
+ add_flagsvers(\%res, 'REQUIRENAME', 'REQUIREFLAGS', 'REQUIREVERSION');
my $data = {
name => $res{'NAME'}->[0],
hdrmd5 => unpack('H32', $res{'SIGTAG_MD5'}->[0]),