aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--rpmtools.pm99
-rw-r--r--rpmtools.spec9
-rw-r--r--rpmtools.xs74
4 files changed, 118 insertions, 66 deletions
diff --git a/Makefile b/Makefile
index 23b30b5..a240c4a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION = 3.0
+VERSION = 3.1
NAME = rpmtools
FROMC = parsehdlist rpm2header #rpm-find-leaves
FROMCC = #gendepslist2 hdlist2names hdlist2files hdlist2prereq hdlist2groups
diff --git a/rpmtools.pm b/rpmtools.pm
index 5a96fd6..ab7e7d8 100644
--- a/rpmtools.pm
+++ b/rpmtools.pm
@@ -200,6 +200,19 @@ sub compute_id {
#- existing entries, as the array here is used instead of values of infos.
my @info = grep { ! exists $_->{id} } values %{$params->{info}};
+ #- speed up the search by giving a provide from all packages.
+ #- and remove all dobles for each one !
+ foreach (@info) {
+ push @{$params->{provides}{$_->{name}} ||= []}, "$_->{name}-$_->{version}-$_->{release}.$_->{arch}";
+ }
+
+ #- remove all dobles for each provides.
+ foreach (keys %{$params->{provides}}) {
+ $params->{provides}{$_} or next;
+ my %provides; @provides{@{$params->{provides}{$_}}} = ();
+ $params->{provides}{$_} = [ keys %provides ];
+ }
+
#- give an id to each packages, start from number of package already
#- registered in depslist.
my $global_id = scalar @{$params->{depslist}};
@@ -223,7 +236,7 @@ sub compute_depslist {
#- speed up the search by giving a provide from all packages.
#- and remove all dobles for each one !
foreach (@info) {
- push @{$params->{provides}{$_->{name}} ||= []}, $_->{name};
+ push @{$params->{provides}{$_->{name}} ||= []}, "$_->{name}-$_->{version}-$_->{release}.$_->{arch}";
}
#- remove all dobles for each provides.
@@ -244,9 +257,10 @@ sub compute_depslist {
my @requires = keys %requires;
while (my $req = shift @requires) {
- $req eq 'basesystem' and next; #- never need to requires basesystem directly as always required! what a speed up!
- ref $req or $req = $params->{provides}{$req} || ($req =~ /rpmlib\(/ ? [] :
- [ ($req !~ /NOTFOUND_/ && "NOTFOUND_") . $req ]);
+ $req =~ /^basesystem/ and next; #- never need to requires basesystem directly as always required! what a speed up!
+ ref $req or $req = ($params->{info}{$req} && [ $req ] ||
+ $params->{provides}{$req} ||
+ ($req =~ /rpmlib\(/ ? [] : [ ($req !~ /NOTFOUND_/ && "NOTFOUND_") . $req ]));
if (@$req > 1) {
#- this is a choice, no closure need to be done here.
exists $requires{$req} or push @required_packages, $req;
@@ -289,7 +303,7 @@ sub compute_depslist {
my %ordered;
foreach (@info) {
my %requires;
- my @requires = ($_->{name});
+ my @requires = ("$_->{name}-$_->{version}-$_->{release}.$_->{arch}");
while (my $dep = shift @requires) {
foreach (@{$params->{info}{$dep} && $params->{info}{$dep}{requires} || []}) {
if (ref $_) {
@@ -318,25 +332,38 @@ sub compute_depslist {
}
}
}
- #- setup, filesystem and basesystem should be at the beginning.
- @ordered{qw(ldconfig readline termcap libtermcap2 bash sash glibc setup filesystem basesystem)} =
- (100000, 90000, 80000, 70000, 60000, 50000, 40000, 30000, 20000, 10000);
+
+ #- some package should be sorted at the beginning.
+ my $fixed_weight = 10000;
+ foreach (qw(basesystem filesystem setup glibc sash bash libtermcap2 termcap readline ldconfig)) {
+ foreach (@{$params->{provides}{$_} || []}) {
+ $ordered{$_} = $fixed_weight;
+ }
+ $fixed_weight += 10000;
+ }
#- compute base flag, consists of packages which are required without
#- choices of basesystem and are ALWAYS installed. these packages can
#- safely be removed from requires of others packages.
- foreach (@{$params->{info}{basesystem}{requires}}) {
- ref $_ or $params->{info}{$_} and $params->{info}{$_}{base} = undef;
+ foreach (@{$params->{provides}{basesystem} || []}) {
+ foreach (@{$params->{info}{$_}{requires}}) {
+ ref $_ or $params->{info}{$_} and $params->{info}{$_}{base} = undef;
+ }
}
+
#- some package are always installed as base and can safely be marked as such.
- foreach (qw(basesystem glibc)) {
- $params->{info}{$_} and $params->{info}{$_}{base} = undef;
+ foreach (qw(basesystem glibc kernel)) {
+ foreach (@{$params->{provides}{$_} || []}) {
+ $params->{info}{$_} and $params->{info}{$_}{base} = undef;
+ }
}
#- give an id to each packages, start from number of package already
#- registered in depslist.
my $global_id = scalar @{$params->{depslist}};
- foreach (sort { $ordered{$b->{name}} <=> $ordered{$a->{name}} || package_name_compare($a->{name}, $b->{name}) } @info) {
+ foreach (sort { ($ordered{"$b->{name}-$b->{version}-$b->{release}.$b->{arch}"} <=>
+ $ordered{"$a->{name}-$a->{version}-$a->{release}.$a->{arch}"}) ||
+ package_name_compare($a->{name}, $b->{name}) } @info) {
$_->{id} = $global_id++;
}
@@ -362,7 +389,11 @@ sub compute_depslist {
#- if a base package is in a list, keep it instead of the choice.
if (@choices_base_id) {
- ($id, $base) = ($choices_base_id[0], 1);
+ @choices_id = @choices_base_id;
+ $base = 1;
+ }
+ if (@choices_id == 1) {
+ $id = $choices_id[0];
} else {
my $choices_key = join '|', @choices_id;
exists $requires_id{$choices_key} or push @requires_id, \@choices_id;
@@ -397,28 +428,34 @@ sub read_depslist {
/^([^:\s]*)-([^:\-\s]+)-([^:\-\s]+)\.([^:\.\-\s]*)(?::(\d+)\S*)?\s+(\d+)\s*(.*)/;
#- store values here according to it.
- push @{$params->{depslist}}, $params->{info}{$name} = {
- name => $name,
- version => $version,
- release => $release,
- arch => $arch,
- $serial ? (serial => $serial) : (),
- size => $size,
- deps => $deps,
- id => $global_id++,
- };
+ push @{$params->{depslist}},
+ $params->{info}{"$name-$version-$release.$arch"} = {
+ name => $name,
+ version => $version,
+ release => $release,
+ arch => $arch,
+ $serial ? (serial => $serial) : (),
+ size => $size,
+ deps => $deps,
+ id => $global_id++,
+ };
+ #- this can be really usefull as there are no more hash on name directly,
+ #- but provides gives something quite interesting here.
+ push @{$params->{provides}{$name}}, "$name-$version-$release.$arch";
}
#- compute base flag, consists of packages which are required without
#- choices of basesystem and are ALWAYS installed. these packages can
#- safely be removed from requires of others packages.
- if ($params->{info}{basesystem} && ! exists $params->{info}{basesystem}{base}) {
- my @requires_id;
- foreach (split ' ', $params->{info}{basesystem}{deps}) {
- /\|/ or push @requires_id, $_;
- }
- foreach ($params->{info}{basesystem}{id}, @requires_id) {
- $params->{depslist}[$_] and $params->{depslist}[$_]{base} = undef;
+ foreach (@{$params->{provides}{basesystem} || []}) {
+ if ($params->{info}{$_} && ! exists $params->{info}{$_}{base}) {
+ my @requires_id;
+ foreach (split ' ', $params->{info}{$_}{deps}) {
+ /\|/ or push @requires_id, $_;
+ }
+ foreach ($params->{info}{$_}{id}, @requires_id) {
+ $params->{depslist}[$_] and $params->{depslist}[$_]{base} = undef;
+ }
}
}
1;
diff --git a/rpmtools.spec b/rpmtools.spec
index 1aeed61..8b9b694 100644
--- a/rpmtools.spec
+++ b/rpmtools.spec
@@ -1,8 +1,8 @@
%define name rpmtools
-%define release 10mdk
+%define release 1mdk
# do not modify here, see Makefile in the CVS
-%define version 3.0
+%define version 3.1
%{expand:%%define perlbase_version %(rpm -q --queryformat '%{VERSION}' perl-base)}
%{expand:%%define rpm_version %(rpm -q --queryformat '%{VERSION}-%{RELEASE}' rpm)}
@@ -54,6 +54,11 @@ rm -rf $RPM_BUILD_ROOT
%{_libdir}/perl5/man/*/*
%changelog
+* Mon Jul 23 2001 François Pons <fpons@mandrakesoft.com> 3.1-1mdk
+- allow provides on full package name.
+- fixed multiple version, release or arch of the same
+ package in the same hdlist.
+
* Sat Jul 21 2001 Warly <warly@mandrakesoft.com> 3.0-10mdk
- add sourcerpm tag.
diff --git a/rpmtools.xs b/rpmtools.xs
index 25d2abf..d96af31 100644
--- a/rpmtools.xs
+++ b/rpmtools.xs
@@ -99,6 +99,31 @@ int get_bflag(AV* flag) {
return bflag;
}
+SV *get_fullname_sv(Header header) {
+ char *name = get_name(header, RPMTAG_NAME);
+ char *version = get_name(header, RPMTAG_VERSION);
+ char *release = get_name(header, RPMTAG_RELEASE);
+ char *arch = get_name(header, RPMTAG_ARCH);
+ char *fullname = (char*)alloca(strlen(name)+strlen(version)+strlen(release)+strlen(arch)+4);
+ STRLEN fullname_len = sprintf(fullname, "%s-%s-%s.%s", name, version, release, arch);
+ return newSVpv(fullname, fullname_len);
+}
+
+void update_provides(int force, HV* provides, char *name, STRLEN len, Header header) {
+ SV** isv;
+
+ if (!len) len = strlen(name);
+
+ if (force && (isv = hv_fetch(provides, name, len, 1)) || provides && (isv = hv_fetch(provides, name, len, 0)) != 0) {
+ if (!SvROK(*isv) || SvTYPE(SvRV(*isv)) != SVt_PVAV) {
+ SV* choice_table = (SV*)newAV();
+ SvREFCNT_dec(*isv); /* drop the old as we are changing it */
+ *isv = choice_table ? newRV_noinc(choice_table) : &PL_sv_undef;
+ }
+ if (*isv != &PL_sv_undef) av_push((AV*)SvRV(*isv), get_fullname_sv(header));
+ }
+}
+
SV *get_table_sense(Header header, int_32 tag_name, int_32 tag_flags, int_32 tag_version, HV* iprovides) {
AV* table_sense;
int_32 type, count;
@@ -223,20 +248,10 @@ HV* get_info(Header header, int bflag, HV* provides) {
headerGetEntry(header, RPMTAG_OLDFILENAMES, &type, (void **) &list, &count);
if (list) {
for (i = 0; i < count; i++) {
- SV** isv;
-
len = strlen(list[i]);
- if (provides && (isv = hv_fetch(provides, list[i], len, 0)) != 0) {
- if (!SvROK(*isv) || SvTYPE(SvRV(*isv)) != SVt_PVAV) {
- SV* choice_table = (SV*)newAV();
- SvREFCNT_dec(*isv); /* drop the old as we are changing it */
- *isv = choice_table ? newRV_noinc(choice_table) : &PL_sv_undef;
- }
- if (*isv != &PL_sv_undef) av_push((AV*)SvRV(*isv), SvREFCNT_inc(sv_name));
- }
- /* if (provides && hv_exists(provides, list[i], len))
- hv_store(provides, list[i], len, newSVpv(name, 0), 0); */
+ update_provides(0, provides, list[i], len, header);
+
if (table_files)
av_push(table_files, newSVpv(list[i], len));
if (table_conffiles && flags && flags[i] & RPMFILE_CONFIG)
@@ -261,14 +276,8 @@ HV* get_info(Header header, int bflag, HV* provides) {
if (p - buff + len >= sizeof(buff)) continue;
memcpy(p, baseNames[i], len + 1); p += len;
- if (provides && (isv = hv_fetch(provides, buff, p - buff, 0)) != 0) {
- if (!SvROK(*isv) || SvTYPE(SvRV(*isv)) != SVt_PVAV) {
- SV* choice_table = (SV*)newAV();
- SvREFCNT_dec(*isv); /* drop the old as we are changing it */
- *isv = choice_table ? newRV_noinc(choice_table) : &PL_sv_undef;
- }
- if (*isv != &PL_sv_undef) av_push((AV*)SvRV(*isv), SvREFCNT_inc(sv_name));
- }
+ update_provides(0, provides, buff, p - buff, header);
+
if (table_files)
av_push(table_files, newSVpv(buff, p - buff));
if (table_conffiles && flags && flags[i] & RPMFILE_CONFIG)
@@ -287,17 +296,7 @@ HV* get_info(Header header, int bflag, HV* provides) {
if (list) {
for (i = 0; i < count; i++) {
- SV** isv;
-
- len = strlen(list[i]);
-
- isv = hv_fetch(provides, list[i], len, 1);
- if (!SvROK(*isv) || SvTYPE(SvRV(*isv)) != SVt_PVAV) {
- SV* choice_table = (SV*)newAV();
- SvREFCNT_dec(*isv); /* drop the old as we are changing it */
- *isv = choice_table ? newRV_noinc(choice_table) : &PL_sv_undef;
- }
- if (*isv != &PL_sv_undef) av_push((AV*)SvRV(*isv), SvREFCNT_inc(sv_name));
+ update_provides(1, provides, list[i], 0, header); /* force extraction of provides */
}
}
}
@@ -500,6 +499,15 @@ _parse_(fileno_or_rpmfile, flag, info, ...)
while (fd_is_hdlist >= 0 ? (fd_is_hdlist > 0 ?
((header=headerRead(fd, HEADER_MAGIC_YES)) != 0) :
((fd_is_hdlist = -1), rpmReadPackageHeader(fd, &header, &i, NULL, NULL) == 0)) : 0) {
+ SV *fullname_sv = get_fullname_sv(header);
+ HV* header_info = get_info(header, bflag, iprovides);
+
+ hv_store_ent(iinfo, fullname_sv, newRV_noinc((SV*)header_info), 0);
+
+ /* return fullname on stack */
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(fullname_sv));
+#if 0
char *name = get_name(header, RPMTAG_NAME);
char *version = get_name(header, RPMTAG_VERSION);
char *release = get_name(header, RPMTAG_RELEASE);
@@ -511,11 +519,13 @@ _parse_(fileno_or_rpmfile, flag, info, ...)
/* once the hash header_info is built, store a reference to it
in iinfo.
note sv_name is not incremented here, it has the default value of before. */
- hv_store(iinfo, name, strlen(name), newRV_noinc((SV*)header_info), 0);
+ /* hv_store(iinfo, name, strlen(name), newRV_noinc((SV*)header_info), 0); */
+ hv_store(iinfo, fullname, fullname_len, newRV_noinc((SV*)header_info), 0);
/* return fullname on stack */
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv(fullname, fullname_len)));
+#endif
/* dispose of some memory */
headerFree(header);