From c019f7e04986a404b6a556624d06585f5b3fe744 Mon Sep 17 00:00:00 2001 From: Francois Pons Date: Mon, 23 Jul 2001 15:15:32 +0000 Subject: first 3.1 major relase, with fullname in info hash. --- Makefile | 2 +- rpmtools.pm | 99 ++++++++++++++++++++++++++++++++++++++++------------------- rpmtools.spec | 9 ++++-- rpmtools.xs | 74 +++++++++++++++++++++++++------------------- 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 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 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); -- cgit v1.2.1