aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-08-16 19:27:53 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-08-16 19:27:53 +0000
commitbea30fc2186c94ebab97eb1dd65c3cf1894726ac (patch)
tree2c566ecd6cb631efd264904b8d8ce426d0f1fba2
parentb3fe7aa2c3e4e55c3c0f1e2a2307eee97c9b80be (diff)
downloadpaludis-bea30fc2186c94ebab97eb1dd65c3cf1894726ac.tar.gz
paludis-bea30fc2186c94ebab97eb1dd65c3cf1894726ac.tar.xz
Merge branches/ciaranm/virtuals (all changes, r1265 through r1272) to trunk/
-rw-r--r--configure.ac1
-rw-r--r--doc/doxygen.conf.in2
-rw-r--r--paludis/default_config.cc6
-rw-r--r--paludis/dep_list.cc36
-rw-r--r--paludis/ebin.cc5
-rw-r--r--paludis/ebin.sr1
-rw-r--r--paludis/ebuild.cc8
-rw-r--r--paludis/ebuild.sr1
-rw-r--r--paludis/environment.cc69
-rw-r--r--paludis/environment.hh15
-rw-r--r--paludis/mask_reasons.cc4
-rw-r--r--paludis/mask_reasons.hh3
-rw-r--r--paludis/package_database.cc12
-rw-r--r--paludis/package_database.hh2
-rw-r--r--paludis/repositories/Makefile.am2
-rw-r--r--paludis/repositories/cran/cran_installed_repository.cc16
-rw-r--r--paludis/repositories/cran/cran_installed_repository.hh4
-rw-r--r--paludis/repositories/cran/cran_repository.cc16
-rw-r--r--paludis/repositories/cran/cran_repository.hh5
-rw-r--r--paludis/repositories/fake/fake_repository.cc15
-rw-r--r--paludis/repositories/fake/fake_repository.hh4
-rw-r--r--paludis/repositories/nothing/nothing_repository.cc16
-rw-r--r--paludis/repositories/nothing/nothing_repository.hh4
-rw-r--r--paludis/repositories/portage/portage_repository.cc127
-rw-r--r--paludis/repositories/portage/portage_repository.hh14
-rw-r--r--paludis/repositories/portage/portage_repository_ebin_entries.cc36
-rw-r--r--paludis/repositories/portage/portage_repository_ebuild_entries.cc35
-rw-r--r--paludis/repositories/vdb/vdb_repository.cc228
-rw-r--r--paludis/repositories/vdb/vdb_repository.hh10
-rw-r--r--paludis/repositories/virtuals/Makefile.am56
-rw-r--r--paludis/repositories/virtuals/installed_virtuals_repository.cc301
-rw-r--r--paludis/repositories/virtuals/installed_virtuals_repository.hh94
-rw-r--r--paludis/repositories/virtuals/virtuals_repository.cc290
-rw-r--r--paludis/repositories/virtuals/virtuals_repository.hh90
-rw-r--r--paludis/repositories/virtuals/vr_entry.cc26
-rw-r--r--paludis/repositories/virtuals/vr_entry.hh120
-rw-r--r--paludis/repositories/virtuals/vr_entry.sr16
-rw-r--r--paludis/repository.cc1
-rw-r--r--paludis/repository.hh57
-rw-r--r--paludis/repository.sr20
-rw-r--r--paludis/repository_config_entry.sr2
-rw-r--r--paludis/util/fast_unique_copy.hh84
-rw-r--r--paludis/util/fast_unique_copy_TEST.cc121
-rw-r--r--paludis/util/files.m41
-rw-r--r--paludis/version_metadata.cc23
-rw-r--r--paludis/version_metadata.hh58
-rw-r--r--paludis/version_metadata.sr6
-rw-r--r--src/paludis/query.cc13
48 files changed, 1646 insertions, 430 deletions
diff --git a/configure.ac b/configure.ac
index 7be7fa3..d7644fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -508,6 +508,7 @@ AC_OUTPUT(
paludis/repositories/nothing/Makefile
paludis/repositories/portage/Makefile
paludis/repositories/vdb/Makefile
+ paludis/repositories/virtuals/Makefile
paludis/selinux/Makefile
paludis/tasks/Makefile
paludis/util/Makefile
diff --git a/doc/doxygen.conf.in b/doc/doxygen.conf.in
index 609b3e3..8693f3c 100644
--- a/doc/doxygen.conf.in
+++ b/doc/doxygen.conf.in
@@ -452,7 +452,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = ../paludis ../paludis/args ../paludis/util ../paludis/digests ../paludis/selinux ../paludis/repositories ../paludis/repositories/nothing ../paludis/repositories/portage ../paludis/repositories/vdb ../paludis/repositories/fake ../test ../doc ../src ../src/paludis ../src/qualudis
+INPUT = ../paludis ../paludis/args ../paludis/util ../paludis/digests ../paludis/selinux ../paludis/repositories ../paludis/repositories/nothing ../paludis/repositories/portage ../paludis/repositories/vdb ../paludis/repositories/fake ../paludis/repositories/cran ../paludis/repositories/virtuals ../test ../doc ../src ../src/paludis ../src/qualudis
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
diff --git a/paludis/default_config.cc b/paludis/default_config.cc
index f13e200..4ca6796 100644
--- a/paludis/default_config.cc
+++ b/paludis/default_config.cc
@@ -216,6 +216,12 @@ DefaultConfig::DefaultConfig() :
if (_imp->repos.empty())
throw DefaultConfigError("No repositories specified");
+ /* add virtuals repositories */
+ _imp->repos.push_back(RepositoryConfigEntry("installed_virtuals", -1,
+ AssociativeCollection<std::string, std::string>::Pointer(0)));
+ _imp->repos.push_back(RepositoryConfigEntry("virtuals", -2,
+ AssociativeCollection<std::string, std::string>::Pointer(0)));
+
_imp->repos.sort();
}
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index 5748e63..b5ab54c 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -501,20 +501,38 @@ DepList::visit(const PackageDepAtom * const p)
DepListEntryMatcher(_imp->environment, pp)))
continue;
+#if 0
VersionMetadata::Pointer p_metadata(new VersionMetadata::Ebuild(
merge_entry->metadata->deps.parser));
p_metadata->slot = merge_entry->metadata->slot;
p_metadata->get_ebuild_interface()->virtual_for = stringify(merge_entry->name);
+#else
+ VersionMetadata::ConstPointer p_metadata(0);
+ try
+ {
+ p_metadata = _imp->environment->package_database()->fetch_repository(RepositoryName(
+ "virtuals"))->version_metadata(pp.package(), merge_entry->version);
+ }
+ catch (const NoSuchPackageError & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Error '" + stringify(e.message()) + "' ("
+ + stringify(e.what()) + ") when looking for virtual '" + stringify(pp.package())
+ + "' for merge entry '" + stringify(*merge_entry));
+ }
+#endif
- DepListEntryFlags flags;
- flags.set(dlef_has_predeps);
- flags.set(dlef_has_trypredeps);
- flags.set(dlef_has_postdeps);
- _imp->merge_list.insert(next(merge_entry),
- DepListEntry(pp.package(), merge_entry->version,
- p_metadata, merge_entry->repository, flags,
- SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Pointer(
- new SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Concrete)));
+ if (p_metadata)
+ {
+ DepListEntryFlags flags;
+ flags.set(dlef_has_predeps);
+ flags.set(dlef_has_trypredeps);
+ flags.set(dlef_has_postdeps);
+ _imp->merge_list.insert(next(merge_entry),
+ DepListEntry(pp.package(), merge_entry->version,
+ p_metadata, merge_entry->repository, flags,
+ SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Pointer(
+ new SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Concrete)));
+ }
}
}
diff --git a/paludis/ebin.cc b/paludis/ebin.cc
index 48a4804..e4def1c 100644
--- a/paludis/ebin.cc
+++ b/paludis/ebin.cc
@@ -169,10 +169,7 @@ EbinFetchCommand::EbinFetchCommand(const EbinCommandParams & p,
std::string
EbinInstallCommand::commands() const
{
- if (install_params.merge_only)
- return "merge";
- else
- return "init_bin unpack_bin setup strip preinst merge postinst tidyup";
+ return "init_bin unpack_bin setup strip preinst merge postinst tidyup";
}
bool
diff --git a/paludis/ebin.sr b/paludis/ebin.sr
index 267ca75..20c1837 100644
--- a/paludis/ebin.sr
+++ b/paludis/ebin.sr
@@ -50,7 +50,6 @@ make_class_EbinInstallCommandParams()
key profiles FSEntryCollection::ConstPointer
key expand_vars "AssociativeCollection<std::string, std::string>::ConstPointer"
key disable_cfgpro bool
- key merge_only bool
key slot SlotName
doxygen_comment << "END"
diff --git a/paludis/ebuild.cc b/paludis/ebuild.cc
index cbd8f0a..3fe3dd1 100644
--- a/paludis/ebuild.cc
+++ b/paludis/ebuild.cc
@@ -185,7 +185,6 @@ EbuildMetadataCommand::do_run_command(const std::string & cmd)
_metadata->deps.post_depend_string = f.get("PDEPEND");
_metadata->get_ebuild_interface()->provide_string = f.get("PROVIDE");
_metadata->eapi = f.get("EAPI");
- _metadata->get_ebuild_interface()->virtual_for = "";
if (0 == prog.exit_status())
ok = true;
@@ -290,11 +289,8 @@ EbuildFetchCommand::EbuildFetchCommand(const EbuildCommandParams & p,
std::string
EbuildInstallCommand::commands() const
{
- if (install_params.merge_only)
- return "merge";
- else
- return "init setup unpack compile test install strip preinst "
- "merge postinst tidyup";
+ return "init setup unpack compile test install strip preinst "
+ "merge postinst tidyup";
}
bool
diff --git a/paludis/ebuild.sr b/paludis/ebuild.sr
index 9412957..d2845b4 100644
--- a/paludis/ebuild.sr
+++ b/paludis/ebuild.sr
@@ -58,7 +58,6 @@ make_class_EbuildInstallCommandParams()
key profiles FSEntryCollection::ConstPointer
key expand_vars "AssociativeCollection<std::string, std::string>::ConstPointer"
key disable_cfgpro bool
- key merge_only bool
key slot SlotName
doxygen_comment << "END"
diff --git a/paludis/environment.cc b/paludis/environment.cc
index 13b46d1..1ff1a54 100644
--- a/paludis/environment.cc
+++ b/paludis/environment.cc
@@ -136,6 +136,13 @@ Environment::mask_reasons(const PackageDatabaseEntry & e) const
result.set(mr_eapi);
else
{
+ if (metadata->get_virtual_interface())
+ {
+ result |= mask_reasons(metadata->get_virtual_interface()->virtual_for);
+ if (result.any())
+ result.set(mr_by_association);
+ }
+
if (metadata->get_ebuild_interface())
{
std::set<KeywordName> keywords;
@@ -151,25 +158,6 @@ Environment::mask_reasons(const PackageDatabaseEntry & e) const
result.reset(mr_keyword);
break;
}
-
- if (! metadata->get_ebuild_interface()->virtual_for.empty())
- {
- QualifiedPackageName n(metadata->get_ebuild_interface()->virtual_for);
-
- PackageDatabaseEntry ee(n, e.version, e.repository);
- std::set<KeywordName> keywords;
- WhitespaceTokeniser::get_instance()->tokenise(
- metadata->get_ebuild_interface()->keywords,
- create_inserter<KeywordName>(std::inserter(keywords, keywords.end())));
-
- for (std::set<KeywordName>::const_iterator i(keywords.begin()),
- i_end(keywords.end()) ; i != i_end ; ++i)
- if (accept_keyword(*i, &ee))
- {
- result.reset(mr_keyword);
- break;
- }
- }
}
LicenceChecker lc(this, &e);
@@ -194,20 +182,6 @@ Environment::mask_reasons(const PackageDatabaseEntry & e) const
if (repo->mask_interface->query_repository_masks(e.name,
e.version))
result.set(mr_repository_mask);
-
- if (metadata->get_ebuild_interface())
- if (! metadata->get_ebuild_interface()->virtual_for.empty())
- {
- QualifiedPackageName n(metadata->get_ebuild_interface()->virtual_for);
-
- if (repo->mask_interface->query_profile_masks(n,
- e.version))
- result.set(mr_profile_mask);
-
- if (repo->mask_interface->query_repository_masks(n,
- e.version))
- result.set(mr_repository_mask);
- }
}
}
}
@@ -215,35 +189,6 @@ Environment::mask_reasons(const PackageDatabaseEntry & e) const
return result;
}
-Environment::ProvideMapIterator
-Environment::begin_provide_map() const
-{
- if (! _has_provide_map)
- {
- Context context("When scanning for PROVIDEs:");
-
- for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
- r_end(package_database()->end_repositories()) ; r != r_end ; ++r)
- {
- if (! (*r)->installed_interface)
- continue;
-
- std::copy((*r)->begin_provide_map(), (*r)->end_provide_map(),
- std::inserter(_provide_map, _provide_map.begin()));
- }
-
- _has_provide_map = true;
- }
-
- return _provide_map.begin();
-}
-
-Environment::ProvideMapIterator
-Environment::end_provide_map() const
-{
- return _provide_map.end();
-}
-
DepAtom::Pointer
Environment::package_set(const std::string & s, const PackageSetOptions & o) const
{
diff --git a/paludis/environment.hh b/paludis/environment.hh
index 1461490..b91d500 100644
--- a/paludis/environment.hh
+++ b/paludis/environment.hh
@@ -188,21 +188,6 @@ namespace paludis
virtual ~Environment();
/**
- * Iterator over our provide map.
- */
- typedef std::map<QualifiedPackageName, QualifiedPackageName>::const_iterator ProvideMapIterator;
-
- /**
- * Iterator to the start of our provide map.
- */
- ProvideMapIterator begin_provide_map() const;
-
- /**
- * Iterator to past the end of our provide map.
- */
- ProvideMapIterator end_provide_map() const;
-
- /**
* Iterator over named mirror entries.
*/
typedef EnvironmentMirrorIterator MirrorIterator;
diff --git a/paludis/mask_reasons.cc b/paludis/mask_reasons.cc
index d26dbc3..cea4c81 100644
--- a/paludis/mask_reasons.cc
+++ b/paludis/mask_reasons.cc
@@ -59,6 +59,10 @@ paludis::operator<< (std::ostream & s, const MaskReason & r)
s << "license";
continue;
+ case mr_by_association:
+ s << "by association";
+ continue;
+
case last_mr:
;
}
diff --git a/paludis/mask_reasons.hh b/paludis/mask_reasons.hh
index da40443..a510c43 100644
--- a/paludis/mask_reasons.hh
+++ b/paludis/mask_reasons.hh
@@ -47,7 +47,8 @@ namespace paludis
mr_repository_mask, ///< repository package.mask
mr_eapi, ///< unknown eapi
mr_license, ///< unaccepted license
- mr_licence = mr_license, ///< convenience alias for those who can spell
+ mr_licence = mr_license, ///< convenience alias for those who can spell,
+ mr_by_association, ///< masked by association with another package (for virtuals)
last_mr ///< number of entries
};
diff --git a/paludis/package_database.cc b/paludis/package_database.cc
index cd0bd21..6839e06 100644
--- a/paludis/package_database.cc
+++ b/paludis/package_database.cc
@@ -70,11 +70,13 @@ NoSuchRepositoryError::NoSuchRepositoryError(const std::string & name) throw ()
{
}
+#if 0
NoSuchVersionError::NoSuchVersionError(const std::string & name,
const VersionSpec & version) throw () :
PackageDatabaseLookupError("No version of '" + name + "' named '" + stringify(version) + "'")
{
}
+#endif
/**
* Name data for an AmbiguousPackageNameError.
@@ -282,10 +284,12 @@ PackageDatabase::better_repository(const RepositoryName & r1,
RepositoryName
PackageDatabase::favourite_repository() const
{
- if (_imp->repositories.empty())
- return RepositoryName("unnamed");
- else
- return (*_imp->repositories.begin())->name();
+ for (RepositoryIterator r(_imp->repositories.begin()), r_end(_imp->repositories.end()) ;
+ r != r_end ; ++r)
+ if ((*r)->can_be_favourite_repository())
+ return (*r)->name();
+
+ return RepositoryName("unnamed");
}
PackageDatabaseEntryCollection::Pointer
diff --git a/paludis/package_database.hh b/paludis/package_database.hh
index 9d81b90..e186939 100644
--- a/paludis/package_database.hh
+++ b/paludis/package_database.hh
@@ -195,6 +195,7 @@ namespace paludis
NoSuchRepositoryError(const std::string & name) throw ();
};
+#if 0
/**
* Thrown if there is no Version in a PackageDatabase with the given
* name.
@@ -211,6 +212,7 @@ namespace paludis
NoSuchVersionError(const std::string & pkg_name,
const VersionSpec & version) throw ();
};
+#endif
/**
* Do we want installed, uninstalled or either when querying?
diff --git a/paludis/repositories/Makefile.am b/paludis/repositories/Makefile.am
index bfaa41f..69fc8a5 100644
--- a/paludis/repositories/Makefile.am
+++ b/paludis/repositories/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = cran fake nothing portage vdb
+SUBDIRS = cran fake nothing portage vdb virtuals
CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
MAINTAINERCLEANFILES = Makefile.in
diff --git a/paludis/repositories/cran/cran_installed_repository.cc b/paludis/repositories/cran/cran_installed_repository.cc
index 53d8a65..d099e2a 100644
--- a/paludis/repositories/cran/cran_installed_repository.cc
+++ b/paludis/repositories/cran/cran_installed_repository.cc
@@ -167,7 +167,9 @@ CRANInstalledRepository::CRANInstalledRepository(const CRANInstalledRepositoryPa
.use_interface(0)
.world_interface(this)
.environment_variable_interface(0)
- .mirrors_interface(0)),
+ .mirrors_interface(0)
+ .virtuals_interface(0)
+ .provides_interface(0)),
PrivateImplementationPattern<CRANInstalledRepository>(new Implementation<CRANInstalledRepository>(p))
{
RepositoryInfoSection::Pointer config_info(new RepositoryInfoSection("Configuration information"));
@@ -503,18 +505,6 @@ CRANInstalledRepository::invalidate() const
_imp->invalidate();
}
-Repository::ProvideMapIterator
-CRANInstalledRepository::begin_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
-Repository::ProvideMapIterator
-CRANInstalledRepository::end_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
void
CRANInstalledRepository::add_to_world(const QualifiedPackageName & n) const
{
diff --git a/paludis/repositories/cran/cran_installed_repository.hh b/paludis/repositories/cran/cran_installed_repository.hh
index d9309b6..963bed0 100644
--- a/paludis/repositories/cran/cran_installed_repository.hh
+++ b/paludis/repositories/cran/cran_installed_repository.hh
@@ -110,10 +110,6 @@ namespace paludis
virtual void invalidate() const;
- virtual ProvideMapIterator begin_provide_map() const;
-
- virtual ProvideMapIterator end_provide_map() const;
-
virtual void add_to_world(const QualifiedPackageName &) const;
virtual void remove_from_world(const QualifiedPackageName &) const;
diff --git a/paludis/repositories/cran/cran_repository.cc b/paludis/repositories/cran/cran_repository.cc
index 7cf809a..bf229c4 100644
--- a/paludis/repositories/cran/cran_repository.cc
+++ b/paludis/repositories/cran/cran_repository.cc
@@ -192,7 +192,9 @@ CRANRepository::CRANRepository(const CRANRepositoryParams & p) :
.use_interface(0)
.world_interface(0)
.environment_variable_interface(0)
- .mirrors_interface(0)),
+ .mirrors_interface(0)
+ .provides_interface(0)
+ .virtuals_interface(0)),
PrivateImplementationPattern<CRANRepository>(new Implementation<CRANRepository>(p))
{
RepositoryInfoSection::Pointer config_info(new RepositoryInfoSection("Configuration information"));
@@ -611,15 +613,3 @@ CRANRepository::invalidate() const
_imp->invalidate();
}
-Repository::ProvideMapIterator
-CRANRepository::begin_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
-Repository::ProvideMapIterator
-CRANRepository::end_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
diff --git a/paludis/repositories/cran/cran_repository.hh b/paludis/repositories/cran/cran_repository.hh
index 6e209c5..64009a5 100644
--- a/paludis/repositories/cran/cran_repository.hh
+++ b/paludis/repositories/cran/cran_repository.hh
@@ -113,11 +113,6 @@ namespace paludis
virtual ~CRANRepository();
virtual void invalidate() const;
-
- virtual ProvideMapIterator begin_provide_map() const;
-
- virtual ProvideMapIterator end_provide_map() const;
-
};
/**
diff --git a/paludis/repositories/fake/fake_repository.cc b/paludis/repositories/fake/fake_repository.cc
index ec052af..d54dea4 100644
--- a/paludis/repositories/fake/fake_repository.cc
+++ b/paludis/repositories/fake/fake_repository.cc
@@ -82,7 +82,8 @@ FakeRepository::FakeRepository(const RepositoryName & name) :
.world_interface(0)
.environment_variable_interface(0)
.mirrors_interface(0)
- ),
+ .virtuals_interface(0)
+ .provides_interface(0)),
RepositoryMaskInterface(),
RepositoryUseInterface(),
PrivateImplementationPattern<FakeRepository>(new Implementation<FakeRepository>)
@@ -257,15 +258,3 @@ FakeRepository::invalidate() const
{
}
-Repository::ProvideMapIterator
-FakeRepository::begin_provide_map() const
-{
- return _imp->provide_map.begin();
-}
-
-Repository::ProvideMapIterator
-FakeRepository::end_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
diff --git a/paludis/repositories/fake/fake_repository.hh b/paludis/repositories/fake/fake_repository.hh
index 776ff36..ca0792f 100644
--- a/paludis/repositories/fake/fake_repository.hh
+++ b/paludis/repositories/fake/fake_repository.hh
@@ -134,10 +134,6 @@ namespace paludis
typedef CountedPtr<const FakeRepository, count_policy::InternalCountTag> ConstPointer;
virtual void invalidate() const;
-
- virtual ProvideMapIterator begin_provide_map() const;
-
- virtual ProvideMapIterator end_provide_map() const;
};
}
diff --git a/paludis/repositories/nothing/nothing_repository.cc b/paludis/repositories/nothing/nothing_repository.cc
index 4132269..67a7144 100644
--- a/paludis/repositories/nothing/nothing_repository.cc
+++ b/paludis/repositories/nothing/nothing_repository.cc
@@ -98,7 +98,9 @@ NothingRepository::NothingRepository(const NothingRepositoryParams & p) try :
.use_interface(0)
.world_interface(0)
.environment_variable_interface(0)
- .mirrors_interface(0)),
+ .mirrors_interface(0)
+ .virtuals_interface(0)
+ .provides_interface(0)),
PrivateImplementationPattern<NothingRepository>(new Implementation<NothingRepository>(p))
{
RepositoryInfoSection::Pointer config_info(new RepositoryInfoSection("Configuration information"));
@@ -240,15 +242,3 @@ NothingRepository::invalidate() const
{
}
-Repository::ProvideMapIterator
-NothingRepository::begin_provide_map() const
-{
- return _imp->provide_map.begin();
-}
-
-Repository::ProvideMapIterator
-NothingRepository::end_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
diff --git a/paludis/repositories/nothing/nothing_repository.hh b/paludis/repositories/nothing/nothing_repository.hh
index f5728c5..ba89fe4 100644
--- a/paludis/repositories/nothing/nothing_repository.hh
+++ b/paludis/repositories/nothing/nothing_repository.hh
@@ -91,10 +91,6 @@ namespace paludis
virtual void invalidate() const;
- virtual ProvideMapIterator begin_provide_map() const;
-
- virtual ProvideMapIterator end_provide_map() const;
-
typedef CountedPtr<NothingRepository, count_policy::InternalCountTag> Pointer;
typedef CountedPtr<const NothingRepository, count_policy::InternalCountTag> ConstPointer;
};
diff --git a/paludis/repositories/portage/portage_repository.cc b/paludis/repositories/portage/portage_repository.cc
index 97312ae..bbd4220 100644
--- a/paludis/repositories/portage/portage_repository.cc
+++ b/paludis/repositories/portage/portage_repository.cc
@@ -244,7 +244,8 @@ PortageRepository::PortageRepository(const PortageRepositoryParams & p) :
.world_interface(0)
.environment_variable_interface(this)
.mirrors_interface(this)
- ),
+ .virtuals_interface(this)
+ .provides_interface(0)),
PrivateImplementationPattern<PortageRepository>(new Implementation<PortageRepository>(this, p))
{
// the info_vars and info_pkgs info is only added on demand, since it's
@@ -294,8 +295,10 @@ PortageRepository::do_has_package_named(const QualifiedPackageName & q) const
need_category_names();
+#if 0
if (q.category == CategoryNamePart("virtual"))
need_virtual_names();
+#endif
CategoryMap::iterator cat_iter(_imp->category_names.find(q.category));
@@ -374,8 +377,10 @@ PortageRepository::do_package_names(const CategoryNamePart & c) const
+ "' in " + stringify(name()) + ":");
need_category_names();
+#if 0
if (c == CategoryNamePart("virtual"))
need_virtual_names();
+#endif
if (_imp->category_names.end() == _imp->category_names.find(c))
return QualifiedPackageNameCollection::Pointer(new QualifiedPackageNameCollection::Concrete);
@@ -464,8 +469,10 @@ PortageRepository::need_category_names() const
void
PortageRepository::need_version_names(const QualifiedPackageName & n) const
{
+#if 0
if (n.category == CategoryNamePart("virtual"))
need_virtual_names();
+#endif
if (_imp->package_names[n])
return;
@@ -635,47 +642,6 @@ PortageRepository::do_query_use_force(const UseFlagName & u, const PackageDataba
return _imp->profile_ptr->use_forced(u, e);
}
-void
-PortageRepository::need_virtual_names() const
-{
- if (_imp->has_virtuals)
- return;
-
- _imp->has_virtuals = true;
-
- try
- {
- _imp->need_profiles();
- need_category_names();
-
- // don't use std::copy!
- for (PortageRepositoryProfile::VirtualsIterator i(_imp->profile_ptr->begin_virtuals()),
- i_end(_imp->profile_ptr->end_virtuals()) ; i != i_end ; ++i)
- _imp->our_virtuals.insert(*i);
-
- for (Environment::ProvideMapIterator p(_imp->params.environment->begin_provide_map()),
- p_end(_imp->params.environment->end_provide_map()) ; p != p_end ; ++p)
- {
- if (! has_package_named(p->second))
- continue;
-
- _imp->our_virtuals.erase(p->first);
- _imp->our_virtuals.insert(std::make_pair(p->first, PackageDepAtom::Pointer(
- new PackageDepAtom(p->second))));
- }
-
- for (VirtualsMap::const_iterator
- v(_imp->our_virtuals.begin()), v_end(_imp->our_virtuals.end()) ;
- v != v_end ; ++v)
- _imp->package_names.insert(std::make_pair(v->first, false));
- }
- catch (...)
- {
- _imp->has_virtuals = false;
- throw;
- }
-}
-
bool
PortageRepository::do_is_arch_flag(const UseFlagName & u) const
{
@@ -842,18 +808,6 @@ PortageRepository::invalidate() const
_imp->invalidate();
}
-Repository::ProvideMapIterator
-PortageRepository::begin_provide_map() const
-{
- return _imp->provide_map.begin();
-}
-
-Repository::ProvideMapIterator
-PortageRepository::end_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
void
PortageRepository::update_news() const
{
@@ -958,20 +912,6 @@ PortageRepository::profile_variable(const std::string & s) const
return _imp->profile_ptr->environment_variable(s);
}
-PortageRepository::OurVirtualsIterator
-PortageRepository::end_our_virtuals() const
-{
- need_virtual_names();
- return OurVirtualsIterator(_imp->our_virtuals.end());
-}
-
-PortageRepository::OurVirtualsIterator
-PortageRepository::find_our_virtuals(const QualifiedPackageName & q) const
-{
- need_virtual_names();
- return OurVirtualsIterator(_imp->our_virtuals.find(q));
-}
-
PortageRepository::MirrorsIterator
PortageRepository::begin_mirrors(const std::string & s) const
{
@@ -986,4 +926,55 @@ PortageRepository::end_mirrors(const std::string & s) const
return MirrorsIterator(_imp->mirrors.equal_range(s).second);
}
+PortageRepository::VirtualsCollection::ConstPointer
+PortageRepository::virtual_packages() const
+{
+ Context context("When loading virtual packages for repository '" +
+ stringify(name()) + "'");
+
+ Log::get_instance()->message(ll_debug, lc_context, "Loading virtual packages for repository '"
+ + stringify(name()) + "'");
+
+ _imp->need_profiles();
+ need_category_names();
+
+ VirtualsCollection::Pointer result(new VirtualsCollection::Concrete);
+
+ for (PortageRepositoryProfile::VirtualsIterator i(_imp->profile_ptr->begin_virtuals()),
+ i_end(_imp->profile_ptr->end_virtuals()) ; i != i_end ; ++i)
+ {
+ if (stringify(i->second->package()) != stringify(*i->second))
+ Log::get_instance()->message(ll_qa, lc_context, "Stripping virtual '"
+ + stringify(i->first) + "' provider '" + stringify(*i->second) + "' to '" +
+ stringify(i->second->package()) + "'");
+
+ result->insert(RepositoryVirtualsEntry::create()
+ .provided_by_name(i->second->package())
+ .virtual_name(i->first));
+ }
+
+ Log::get_instance()->message(ll_debug, lc_context, "Loaded " + stringify(result->size()) +
+ " virtual packages for repository '" + stringify(name()) + "'");
+
+ return result;
+}
+
+VersionMetadata::ConstPointer
+PortageRepository::virtual_package_version_metadata(const RepositoryVirtualsEntry & p,
+ const VersionSpec & v) const
+{
+ VersionMetadata::ConstPointer m(version_metadata(p.provided_by_name, v));
+ VersionMetadata::Virtual::Pointer result(new VersionMetadata::Virtual(
+ PortageDepParser::parse_depend, PackageDatabaseEntry(p.provided_by_name, v, name())));
+
+ result->slot = m->slot;
+ result->license_string = m->license_string;
+ result->eapi = m->eapi;
+ result->deps = VersionMetadataDeps(&PortageDepParser::parse_depend,
+ "=" + stringify(p.provided_by_name) + "-" + stringify(v),
+ "=" + stringify(p.provided_by_name) + "-" + stringify(v), "");
+
+ return result;
+
+}
diff --git a/paludis/repositories/portage/portage_repository.hh b/paludis/repositories/portage/portage_repository.hh
index ea22658..195632f 100644
--- a/paludis/repositories/portage/portage_repository.hh
+++ b/paludis/repositories/portage/portage_repository.hh
@@ -54,12 +54,12 @@ namespace paludis
public RepositorySetsInterface,
public RepositoryEnvironmentVariableInterface,
public RepositoryMirrorsInterface,
+ public RepositoryVirtualsInterface,
private PrivateImplementationPattern<PortageRepository>
{
private:
void need_category_names() const;
void need_version_names(const QualifiedPackageName &) const;
- void need_virtual_names() const;
void need_mirrors() const;
PackageDatabaseEntryCollection::Iterator find_best(PackageDatabaseEntryCollection & c,
const PackageDatabaseEntry & e) const;
@@ -117,6 +117,11 @@ namespace paludis
virtual bool do_sync() const;
+ virtual VirtualsCollection::ConstPointer virtual_packages() const;
+
+ virtual VersionMetadata::ConstPointer virtual_package_version_metadata(
+ const RepositoryVirtualsEntry &, const VersionSpec & v) const;
+
public:
virtual RepositoryInfo::ConstPointer info(bool verbose) const;
@@ -132,10 +137,6 @@ namespace paludis
virtual void invalidate() const;
- virtual ProvideMapIterator begin_provide_map() const;
-
- virtual ProvideMapIterator end_provide_map() const;
-
virtual void update_news() const;
virtual std::string get_environment_variable(
@@ -156,9 +157,6 @@ namespace paludis
typedef libwrapiter::ForwardIterator<PortageRepository, std::pair<
const QualifiedPackageName, PackageDepAtom::ConstPointer> > OurVirtualsIterator;
- OurVirtualsIterator end_our_virtuals() const;
- OurVirtualsIterator find_our_virtuals(const QualifiedPackageName &) const;
-
///\}
};
}
diff --git a/paludis/repositories/portage/portage_repository_ebin_entries.cc b/paludis/repositories/portage/portage_repository_ebin_entries.cc
index 7eb8e6e..5040808 100644
--- a/paludis/repositories/portage/portage_repository_ebin_entries.cc
+++ b/paludis/repositories/portage/portage_repository_ebin_entries.cc
@@ -86,7 +86,6 @@ PortageRepositoryEbinEntries::generate_version_metadata(const QualifiedPackageNa
ebin_file /= stringify(q.package);
ebin_file /= (stringify(q.package) + "-" + stringify(v) + ".ebin");
- PortageRepository::OurVirtualsIterator vi(_imp->portage_repository->end_our_virtuals());
if (ebin_file.is_regular_file())
{
KeyValueConfigFile f(ebin_file);
@@ -102,22 +101,10 @@ PortageRepositoryEbinEntries::generate_version_metadata(const QualifiedPackageNa
result->get_ebuild_interface()->restrict_string = f.get("restrict");
result->get_ebuild_interface()->keywords = f.get("keywords");
result->get_ebuild_interface()->iuse = f.get("iuse");
- result->get_ebuild_interface()->virtual_for = f.get("virtual");
result->get_ebuild_interface()->inherited = f.get("inherited");
result->get_ebin_interface()->bin_uri = f.get("bin_uri");
result->get_ebin_interface()->src_repository = RepositoryName(f.get("src_repository"));
}
- else if (_imp->portage_repository->end_our_virtuals() !=
- ((vi = _imp->portage_repository->find_our_virtuals(q))))
- {
- VersionMetadata::ConstPointer m(_imp->portage_repository->version_metadata(
- vi->second->package(), v));
- result->slot = m->slot;
- result->get_ebuild_interface()->keywords = m->get_ebuild_interface()->keywords;
- result->eapi = m->eapi;
- result->get_ebuild_interface()->virtual_for = (stringify(vi->second->package()));
- result->deps.build_depend_string = "=" + stringify(vi->second->package()) + "-" + stringify(v);
- }
else
throw NoSuchPackageError(stringify(PackageDatabaseEntry(q, v, _imp->portage_repository->name())));
@@ -129,22 +116,11 @@ void
PortageRepositoryEbinEntries::install(const QualifiedPackageName & q, const VersionSpec & v,
const InstallOptions & o, PortageRepositoryProfile::ConstPointer p) const
{
- VersionMetadata::ConstPointer metadata(0);
+ VersionMetadata::ConstPointer metadata(_imp->portage_repository->version_metadata(q, v));
+
if (! _imp->portage_repository->has_version(q, v))
- {
- if (q.category == CategoryNamePart("virtual"))
- {
- VersionMetadata::Ebin::Pointer m(new VersionMetadata::Ebin(PortageDepParser::parse_depend));
- m->slot = SlotName("0");
- m->get_ebuild_interface()->virtual_for = " ";
- metadata = m;
- }
- else
- throw PackageInstallActionError("Can't install '" + stringify(q) + "-"
- + stringify(v) + "' since has_version failed");
- }
- else
- metadata = _imp->portage_repository->version_metadata(q, v);
+ throw PackageInstallActionError("Can't install '" + stringify(q) + "-"
+ + stringify(v) + "' since has_version failed");
PackageDatabaseEntry e(q, v, _imp->portage_repository->name());
@@ -305,8 +281,7 @@ PortageRepositoryEbinEntries::install(const QualifiedPackageName & q, const Vers
.root(stringify(_imp->params.root) + "/")
.profiles(_imp->params.profiles));
- if (metadata->get_ebuild_interface()->virtual_for.empty())
- fetch_cmd();
+ fetch_cmd();
if (o.fetch_only)
return;
@@ -330,7 +305,6 @@ PortageRepositoryEbinEntries::install(const QualifiedPackageName & q, const Vers
.root(stringify(_imp->params.root) + "/")
.profiles(_imp->params.profiles)
.disable_cfgpro(o.no_config_protect)
- .merge_only(! metadata->get_ebuild_interface()->virtual_for.empty())
.slot(SlotName(metadata->slot)));
install_cmd();
diff --git a/paludis/repositories/portage/portage_repository_ebuild_entries.cc b/paludis/repositories/portage/portage_repository_ebuild_entries.cc
index 4a255d3..ff897b4 100644
--- a/paludis/repositories/portage/portage_repository_ebuild_entries.cc
+++ b/paludis/repositories/portage/portage_repository_ebuild_entries.cc
@@ -85,7 +85,6 @@ PortageRepositoryEbuildEntries::generate_version_metadata(const QualifiedPackage
cache_file /= stringify(q.package) + "-" + stringify(v);
bool ok(false);
- PortageRepository::OurVirtualsIterator vi(_imp->portage_repository->end_our_virtuals());
if (cache_file.is_regular_file())
{
std::ifstream cache(stringify(cache_file).c_str());
@@ -108,7 +107,6 @@ PortageRepositoryEbuildEntries::generate_version_metadata(const QualifiedPackage
std::getline(cache, line); result->deps.post_depend_string = line;
std::getline(cache, line); result->get_ebuild_interface()->provide_string = line;
std::getline(cache, line); result->eapi = line;
- result->get_ebuild_interface()->virtual_for = "";
// check mtimes
time_t cache_time(cache_file.mtime());
@@ -149,18 +147,6 @@ PortageRepositoryEbuildEntries::generate_version_metadata(const QualifiedPackage
"Couldn't read the cache file at '"
+ stringify(cache_file) + "'");
}
- else if (_imp->portage_repository->end_our_virtuals() !=
- ((vi = _imp->portage_repository->find_our_virtuals(q))))
- {
- VersionMetadata::ConstPointer m(_imp->portage_repository->version_metadata(
- vi->second->package(), v));
- result->slot = m->slot;
- result->get_ebuild_interface()->keywords = m->get_ebuild_interface()->keywords;
- result->eapi = m->eapi;
- result->get_ebuild_interface()->virtual_for = stringify(vi->second->package());
- result->deps.build_depend_string = "=" + stringify(vi->second->package()) + "-" + stringify(v);
- ok = true;
- }
if (! ok)
{
@@ -262,22 +248,13 @@ void
PortageRepositoryEbuildEntries::install(const QualifiedPackageName & q, const VersionSpec & v,
const InstallOptions & o, PortageRepositoryProfile::ConstPointer p) const
{
- VersionMetadata::ConstPointer metadata(0);
if (! _imp->portage_repository->has_version(q, v))
{
- if (q.category == CategoryNamePart("virtual"))
- {
- VersionMetadata::Ebuild::Pointer m(new VersionMetadata::Ebuild(PortageDepParser::parse_depend));
- m->slot = SlotName("0");
- m->get_ebuild_interface()->virtual_for = " ";
- metadata = m;
- }
- else
- throw PackageInstallActionError("Can't install '" + stringify(q) + "-"
- + stringify(v) + "' since has_version failed");
+ throw PackageInstallActionError("Can't install '" + stringify(q) + "-"
+ + stringify(v) + "' since has_version failed");
}
- else
- metadata = _imp->portage_repository->version_metadata(q, v);
+
+ VersionMetadata::ConstPointer metadata(_imp->portage_repository->version_metadata(q, v));
PackageDatabaseEntry e(q, v, _imp->portage_repository->name());
@@ -491,8 +468,7 @@ PortageRepositoryEbuildEntries::install(const QualifiedPackageName & q, const Ve
.profiles(_imp->params.profiles)
.no_fetch(fetch_restrict));
- if (metadata->get_ebuild_interface()->virtual_for.empty())
- fetch_cmd();
+ fetch_cmd();
if (o.fetch_only)
return;
@@ -518,7 +494,6 @@ PortageRepositoryEbuildEntries::install(const QualifiedPackageName & q, const Ve
.root(stringify(_imp->params.root) + "/")
.profiles(_imp->params.profiles)
.disable_cfgpro(o.no_config_protect)
- .merge_only(! metadata->get_ebuild_interface()->virtual_for.empty())
.slot(SlotName(metadata->slot)));
install_cmd();
diff --git a/paludis/repositories/vdb/vdb_repository.cc b/paludis/repositories/vdb/vdb_repository.cc
index 07abc76..f7ecd8a 100644
--- a/paludis/repositories/vdb/vdb_repository.cc
+++ b/paludis/repositories/vdb/vdb_repository.cc
@@ -30,7 +30,9 @@
#include <paludis/util/collection_concrete.hh>
#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/fast_unique_copy.hh>
#include <paludis/util/fs_entry.hh>
+#include <paludis/util/is_file_with_extension.hh>
#include <paludis/util/iterator.hh>
#include <paludis/util/log.hh>
#include <paludis/util/pstream.hh>
@@ -109,6 +111,37 @@ namespace
{
return e.name.category < c;
}
+
+ bool operator() (const VDBEntry & e, const VDBEntry & c) const
+ {
+ return e.name.category < c.name.category;
+ }
+ };
+
+ /**
+ * Extract category from a VDBEntry.
+ *
+ * \ingroup grpvdbrepository
+ */
+ struct ExtractCategory
+ {
+ CategoryNamePart operator() (const VDBEntry & e) const
+ {
+ return e.name.category;
+ }
+ };
+
+ /**
+ * Extract package from a VDBEntry.
+ *
+ * \ingroup grpvdbrepository
+ */
+ struct ExtractPackage
+ {
+ QualifiedPackageName operator() (const VDBEntry & e) const
+ {
+ return e.name;
+ }
};
/**
@@ -127,6 +160,11 @@ namespace
{
return e.name < c;
}
+
+ bool operator() (const VDBEntry & e, const VDBEntry & c) const
+ {
+ return e.name < c.name;
+ }
};
/**
@@ -191,6 +229,18 @@ namespace
return result;
}
+
+ /**
+ * Figure out whether there's an ebuild present (won't be the case for
+ * virtual things installed using early paludis versions).
+ *
+ * \ingroup grpvdbrepository
+ */
+ bool is_ebuilded(const FSEntry & vdb_dir)
+ {
+ return ! std::count_if(DirIterator(vdb_dir), DirIterator(),
+ IsFileWithExtension(".ebuild"));
+ }
}
namespace
@@ -275,12 +325,6 @@ namespace paludis
/// Load metadata for one entry.
void load_entry(std::vector<VDBEntry>::iterator) const;
- /// Do we have provide map loaded?
- mutable bool has_provide_map;
-
- /// Provide map.
- mutable std::map<QualifiedPackageName, QualifiedPackageName> provide_map;
-
/// Constructor.
Implementation(const VDBRepositoryParams &);
@@ -298,8 +342,7 @@ namespace paludis
root(p.root),
buildroot(p.buildroot),
world_file(p.world),
- entries_valid(false),
- has_provide_map(false)
+ entries_valid(false)
{
}
@@ -343,9 +386,6 @@ namespace paludis
{
entries_valid = false;
entries.clear();
-
- has_provide_map = false;
- provide_map.clear();
}
void
@@ -403,7 +443,8 @@ VDBRepository::VDBRepository(const VDBRepositoryParams & p) :
.world_interface(this)
.environment_variable_interface(this)
.mirrors_interface(0)
- ),
+ .provides_interface(this)
+ .virtuals_interface(0)),
PrivateImplementationPattern<VDBRepository>(new Implementation<VDBRepository>(p))
{
RepositoryInfoSection::Pointer config_info(new RepositoryInfoSection("Configuration information"));
@@ -461,9 +502,15 @@ VDBRepository::do_category_names() const
CategoryNamePartCollection::Pointer result(new CategoryNamePartCollection::Concrete);
+#if 0
for (std::vector<VDBEntry>::const_iterator c(_imp->entries.begin()), c_end(_imp->entries.end()) ;
c != c_end ; ++c)
result->insert(c->name.category);
+#else
+ fast_unique_copy(_imp->entries.begin(), _imp->entries.end(),
+ transform_inserter(result->inserter(), VDBEntry::ExtractCategory()),
+ VDBEntry::CompareCategory());
+#endif
return result;
}
@@ -483,9 +530,13 @@ VDBRepository::do_package_names(const CategoryNamePart & c) const
std::pair<std::vector<VDBEntry>::const_iterator, std::vector<VDBEntry>::const_iterator>
r(std::equal_range(_imp->entries.begin(), _imp->entries.end(), c,
VDBEntry::CompareCategory()));
-
+#if 0
for ( ; r.first != r.second ; ++(r.first))
result->insert(r.first->name);
+#endif
+ fast_unique_copy(r.first, r.second,
+ transform_inserter(result->inserter(), VDBEntry::ExtractPackage()),
+ VDBEntry::ComparePackage());
return result;
}
@@ -788,7 +839,7 @@ VDBRepository::do_uninstall(const QualifiedPackageName & q, const VersionSpec &
EbuildUninstallCommandParams::create()
.root(stringify(_imp->root) + "/")
.disable_cfgpro(o.no_config_protect)
- .unmerge_only(! metadata->get_ebuild_interface()->virtual_for.empty())
+ .unmerge_only(is_ebuilded(pkg_dir))
.load_environment(load_env.raw_pointer()));
uninstall_cmd();
@@ -852,76 +903,6 @@ VDBRepository::invalidate() const
_imp->invalidate();
}
-Repository::ProvideMapIterator
-VDBRepository::begin_provide_map() const
-{
- if (! _imp->has_provide_map)
- {
- Context context("When loading VDB PROVIDEs map:");
-
- Log::get_instance()->message(ll_debug, lc_no_context, "Starting VDB PROVIDEs map creation");
-
- if (! _imp->entries_valid)
- _imp->load_entries();
-
- for (std::vector<VDBEntry>::iterator e(_imp->entries.begin()),
- e_end(_imp->entries.end()) ; e != e_end ; ++e)
- {
- Context loop_context("When loading VDB PROVIDEs entry for '"
- + stringify(e->name) + "-" + stringify(e->version) + "':");
-
- try
- {
- if (! e->metadata)
- _imp->load_entry(e);
- const std::string provide_str(e->metadata->get_ebuild_interface()->provide_string);
- if (provide_str.empty())
- continue;
-
- DepAtom::ConstPointer provide(PortageDepParser::parse(provide_str,
- PortageDepParserPolicy<PackageDepAtom, false>::get_instance()));
- PackageDatabaseEntry dbe(e->name, e->version, name());
- DepAtomFlattener f(_imp->env, &dbe, provide);
-
- for (DepAtomFlattener::Iterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
- {
- QualifiedPackageName pp((*p)->text());
-
- if (pp.category != CategoryNamePart("virtual"))
- Log::get_instance()->message(ll_warning, lc_no_context, "PROVIDE of non-virtual '"
- + stringify(pp) + "' from '" + stringify(e->name) + "-"
- + stringify(e->version) + "' in '" + stringify(name())
- + "' will not work as expected");
-
- _imp->provide_map.insert(std::make_pair(pp, e->name));
- }
- }
- catch (const InternalError &)
- {
- throw;
- }
- catch (const Exception & ee)
- {
- Log::get_instance()->message(ll_warning, lc_no_context, "Skipping VDB PROVIDE entry for '"
- + stringify(e->name) + "-" + stringify(e->version) + "' due to exception '"
- + stringify(ee.message()) + "' (" + stringify(ee.what()) + ")");
- }
- }
-
- Log::get_instance()->message(ll_debug, lc_no_context, "Done VDB PROVIDEs map creation");
-
- _imp->has_provide_map = true;
- }
-
- return _imp->provide_map.begin();
-}
-
-Repository::ProvideMapIterator
-VDBRepository::end_provide_map() const
-{
- return _imp->provide_map.end();
-}
-
void
VDBRepository::add_to_world(const QualifiedPackageName & n) const
{
@@ -1047,3 +1028,82 @@ VDBRepository::get_environment_variable(
+ stringify(for_package) + "'");
}
+RepositoryProvidesInterface::ProvidesCollection::ConstPointer
+VDBRepository::provided_packages() const
+{
+ Context context("When loading VDB PROVIDEs map:");
+
+ Log::get_instance()->message(ll_debug, lc_no_context, "Starting VDB PROVIDEs map creation");
+
+ ProvidesCollection::Pointer result(new ProvidesCollection::Concrete);
+
+ if (! _imp->entries_valid)
+ _imp->load_entries();
+
+ for (std::vector<VDBEntry>::iterator e(_imp->entries.begin()),
+ e_end(_imp->entries.end()) ; e != e_end ; ++e)
+ {
+ Context loop_context("When loading VDB PROVIDEs entry for '"
+ + stringify(e->name) + "-" + stringify(e->version) + "':");
+
+ try
+ {
+ if (! e->metadata)
+ _imp->load_entry(e);
+ const std::string provide_str(e->metadata->get_ebuild_interface()->provide_string);
+ if (provide_str.empty())
+ continue;
+
+ DepAtom::ConstPointer provide(PortageDepParser::parse(provide_str,
+ PortageDepParserPolicy<PackageDepAtom, false>::get_instance()));
+ PackageDatabaseEntry dbe(e->name, e->version, name());
+ DepAtomFlattener f(_imp->env, &dbe, provide);
+
+ for (DepAtomFlattener::Iterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
+ {
+ QualifiedPackageName pp((*p)->text());
+
+ if (pp.category != CategoryNamePart("virtual"))
+ Log::get_instance()->message(ll_warning, lc_no_context, "PROVIDE of non-virtual '"
+ + stringify(pp) + "' from '" + stringify(e->name) + "-"
+ + stringify(e->version) + "' in '" + stringify(name())
+ + "' will not work as expected");
+
+ result->insert(RepositoryProvidesEntry::create()
+ .virtual_name(pp)
+ .version(e->version)
+ .provided_by_name(e->name));
+ }
+ }
+ catch (const InternalError &)
+ {
+ throw;
+ }
+ catch (const Exception & ee)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context, "Skipping VDB PROVIDE entry for '"
+ + stringify(e->name) + "-" + stringify(e->version) + "' due to exception '"
+ + stringify(ee.message()) + "' (" + stringify(ee.what()) + ")");
+ }
+ }
+
+ Log::get_instance()->message(ll_debug, lc_no_context, "Done VDB PROVIDEs map creation");
+
+ return result;
+}
+
+VersionMetadata::ConstPointer
+VDBRepository::provided_package_version_metadata(const RepositoryProvidesEntry & p) const
+{
+ VersionMetadata::ConstPointer m(version_metadata(p.provided_by_name, p.version));
+ VersionMetadata::Pointer result(new VersionMetadata(PortageDepParser::parse_depend));
+
+ result->slot = m->slot;
+ result->license_string = m->license_string;
+ result->eapi = m->eapi;
+ result->deps = VersionMetadataDeps(&PortageDepParser::parse_depend,
+ stringify(p.provided_by_name), stringify(p.provided_by_name), "");
+
+ return result;
+}
+
diff --git a/paludis/repositories/vdb/vdb_repository.hh b/paludis/repositories/vdb/vdb_repository.hh
index 5c0793b..f0f2555 100644
--- a/paludis/repositories/vdb/vdb_repository.hh
+++ b/paludis/repositories/vdb/vdb_repository.hh
@@ -52,6 +52,7 @@ namespace paludis
public RepositorySetsInterface,
public RepositoryWorldInterface,
public RepositoryEnvironmentVariableInterface,
+ public RepositoryProvidesInterface,
public PrivateImplementationPattern<VDBRepository>
{
protected:
@@ -117,10 +118,6 @@ namespace paludis
virtual void invalidate() const;
- virtual ProvideMapIterator begin_provide_map() const;
-
- virtual ProvideMapIterator end_provide_map() const;
-
virtual void add_to_world(const QualifiedPackageName &) const;
virtual void remove_from_world(const QualifiedPackageName &) const;
@@ -129,6 +126,11 @@ namespace paludis
const PackageDatabaseEntry & for_package,
const std::string & var) const;
+ virtual ProvidesCollection::ConstPointer provided_packages() const;
+
+ virtual VersionMetadata::ConstPointer provided_package_version_metadata(
+ const RepositoryProvidesEntry &) const;
+
typedef CountedPtr<VDBRepository, count_policy::InternalCountTag> Pointer;
typedef CountedPtr<const VDBRepository, count_policy::InternalCountTag> ConstPointer;
};
diff --git a/paludis/repositories/virtuals/Makefile.am b/paludis/repositories/virtuals/Makefile.am
new file mode 100644
index 0000000..ac5116d
--- /dev/null
+++ b/paludis/repositories/virtuals/Makefile.am
@@ -0,0 +1,56 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+DISTCLEANFILES = vr_entry-sr.hh vr_entry-sr.cc
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\"
+
+paludis_repositories_libdir = $(libdir)/paludis/repositories
+paludis_repositories_lib_LTLIBRARIES = libpaludisvirtualsrepository.la
+paludis_repositories_virtuals_includedir = $(includedir)/paludis/repositories/virtuals/
+libpaludisvirtualsrepository_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+
+paludis_repositories_virtuals_include_HEADERS = \
+ virtuals_repository.hh \
+ installed_virtuals_repository.hh \
+ vr_entry.hh
+
+libpaludisvirtualsrepository_la_SOURCES = \
+ virtuals_repository.cc \
+ installed_virtuals_repository.cc \
+ vr_entry.cc \
+ $(paludis_repositories_portage_include_HEADERS)
+
+EXTRA_DIST = \
+ vr_entry-sr.hh \
+ vr_entry-sr.cc \
+ vr_entry.sr
+
+BUILT_SOURCES = \
+ vr_entry-sr.hh \
+ vr_entry-sr.cc
+
+TESTS =
+
+check_PROGRAMS = $(TESTS)
+check_SCRIPTS =
+
+TESTS_ENVIRONMENT = env \
+ PALUDIS_EBUILD_DIR="$(top_srcdir)/ebuild/" \
+ PALUDIS_SKIP_CONFIG="yes" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \
+ bash $(top_srcdir)/test/run_test.sh
+
+vr_entry-sr.hh : vr_entry.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/vr_entry.sr > $@
+
+vr_entry-sr.cc : vr_entry.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/vr_entry.sr > $@
+
+
+
diff --git a/paludis/repositories/virtuals/installed_virtuals_repository.cc b/paludis/repositories/virtuals/installed_virtuals_repository.cc
new file mode 100644
index 0000000..61d2934
--- /dev/null
+++ b/paludis/repositories/virtuals/installed_virtuals_repository.cc
@@ -0,0 +1,301 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/repositories/virtuals/installed_virtuals_repository.hh>
+#include <paludis/repositories/virtuals/vr_entry.hh>
+#include <paludis/util/fast_unique_copy.hh>
+#include <paludis/environment.hh>
+#include <paludis/package_database.hh>
+#include <paludis/util/compare.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <vector>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<InstalledVirtualsRepository> :
+ InternalCounted<Implementation<InstalledVirtualsRepository> >
+ {
+ const Environment * const env;
+
+ mutable std::vector<VREntry> entries;
+ mutable bool has_entries;
+
+ Implementation(const Environment * const e) :
+ env(e),
+ has_entries(false)
+ {
+ }
+ };
+
+}
+
+InstalledVirtualsRepository::InstalledVirtualsRepository(const Environment * const env) :
+ Repository(RepositoryName("installed_virtuals"), RepositoryCapabilities::create()
+ .installable_interface(0)
+ .mask_interface(this)
+ .installed_interface(this)
+ .use_interface(0)
+ .news_interface(0)
+ .sets_interface(0)
+ .syncable_interface(0)
+ .uninstallable_interface(0)
+ .mirrors_interface(0)
+ .environment_variable_interface(0)
+ .world_interface(0)
+ .provides_interface(0)
+ .virtuals_interface(0)),
+ PrivateImplementationPattern<InstalledVirtualsRepository>(
+ new Implementation<InstalledVirtualsRepository>(env))
+{
+ RepositoryInfoSection::Pointer config_info(new RepositoryInfoSection("Configuration information"));
+ config_info->add_kv("format", "installed_virtuals");
+ _info->add_section(config_info);
+}
+
+InstalledVirtualsRepository::~InstalledVirtualsRepository()
+{
+}
+
+void
+InstalledVirtualsRepository::need_entries() const
+{
+ if (_imp->has_entries)
+ return;
+
+ /* Populate our _imp->entries. We need to iterate over each repository in
+ * our env's package database, see if it has a provides interface, and if it
+ * does create an entry for each provided package. */
+ for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
+ r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
+ {
+ if (! (*r)->provides_interface)
+ continue;
+
+ RepositoryProvidesInterface::ProvidesCollection::ConstPointer pp(
+ (*r)->provides_interface->provided_packages());
+
+ for (RepositoryProvidesInterface::ProvidesCollection::Iterator p(
+ pp->begin()), p_end(pp->end()) ; p != p_end ; ++p)
+ {
+ _imp->entries.push_back(VREntry::create()
+ .virtual_name(p->virtual_name)
+ .version(p->version)
+ .provided_by_name(p->provided_by_name)
+ .provided_by_repository((*r)->name()));
+ }
+ }
+
+ /* Our entries must be sorted, for fast lookups. But it's a bit trickier
+ * than a straight operator< comparison, because the same virtual version
+ * can be provided by more than one thing. For ease of coding elsewhere, we
+ * want the 'best' entry to come earlier (sort lower). We define best as
+ * being from the most important repository, and failing that from the
+ * greater provided name (the second part purely for consistency between
+ * invokations). */
+ std::sort(_imp->entries.begin(), _imp->entries.end(),
+ EntriesComparator(_imp->env->package_database()));
+
+ _imp->has_entries = true;
+}
+
+CountedPtr<Repository>
+InstalledVirtualsRepository::make_installed_virtuals_repository(
+ const Environment * const env,
+ const PackageDatabase * const,
+ AssociativeCollection<std::string, std::string>::ConstPointer)
+{
+ return CountedPtr<Repository>(new InstalledVirtualsRepository(env));
+}
+
+Contents::ConstPointer
+InstalledVirtualsRepository::do_contents(
+ const QualifiedPackageName &, const VersionSpec &) const
+{
+ /* virtual packages don't have any genuine contents. don't return the
+ * content of our real package -- that'll cause extreme confusion with
+ * paludis --owner. */
+
+ return Contents::ConstPointer(new Contents);
+}
+
+bool
+InstalledVirtualsRepository::do_query_repository_masks(const QualifiedPackageName &,
+ const VersionSpec &) const
+{
+ need_entries();
+
+ /// \todo
+ return false;
+}
+
+bool
+InstalledVirtualsRepository::do_query_profile_masks(const QualifiedPackageName &,
+ const VersionSpec &) const
+{
+ need_entries();
+
+ /// \todo
+ return false;
+}
+
+VersionMetadata::ConstPointer
+InstalledVirtualsRepository::do_version_metadata(
+ const QualifiedPackageName & q,
+ const VersionSpec & v) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, v, QualifiedPackageName("dummy/package"), RepositoryName("dummy_repository"))));
+
+ if (p.first == p.second)
+ throw NoSuchPackageError(stringify(PackageDatabaseEntry(q, v, name())));
+
+ return _imp->env->package_database()->fetch_repository(
+ p.first->provided_by_repository)->provides_interface->provided_package_version_metadata(
+ RepositoryProvidesEntry::create()
+ .virtual_name(p.first->virtual_name)
+ .version(p.first->version)
+ .provided_by_name(p.first->provided_by_name));
+}
+
+bool
+InstalledVirtualsRepository::do_has_version(const QualifiedPackageName & q,
+ const VersionSpec & v) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, v, QualifiedPackageName("dummy/package"), RepositoryName("dummy_repository"))));
+
+ return p.first != p.second;
+}
+
+VersionSpecCollection::ConstPointer
+InstalledVirtualsRepository::do_version_specs(const QualifiedPackageName & q) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesNameComparator()));
+
+ VersionSpecCollection::Pointer result(new VersionSpecCollection::Concrete);
+ for ( ; p.first != p.second ; ++p.first)
+ result->insert(p.first->version);
+
+ return result;
+}
+
+QualifiedPackageNameCollection::ConstPointer
+InstalledVirtualsRepository::do_package_names(const CategoryNamePart & c) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(c + PackageNamePart("dummy"), VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesCategoryComparator()));
+
+
+ QualifiedPackageNameCollection::Pointer result(new QualifiedPackageNameCollection::Concrete);
+#if 0
+ /// \todo: in theory, this can be a lot faster
+ for ( ; p.first != p.second ; ++p.first)
+ result->insert(p.first->virtual_name);
+#else
+ fast_unique_copy(p.first, p.second,
+ transform_inserter(result->inserter(), EntriesNameExtractor()),
+ EntriesNameComparator());
+#endif
+
+ return result;
+}
+
+CategoryNamePartCollection::ConstPointer
+InstalledVirtualsRepository::do_category_names() const
+{
+ need_entries();
+
+ CategoryNamePartCollection::Pointer result(new CategoryNamePartCollection::Concrete);
+#if 0
+ /// \todo: in theory, this can be a lot lot lot faster
+ for (std::vector<VREntry>::const_iterator p(_imp->entries.begin()), p_end(_imp->entries.end()) ;
+ p != p_end ; ++p)
+ result->insert(p->virtual_name.category);
+#else
+ fast_unique_copy(_imp->entries.begin(), _imp->entries.end(),
+ transform_inserter(result->inserter(), EntriesCategoryExtractor()),
+ EntriesCategoryComparator());
+#endif
+
+ return result;
+}
+
+bool
+InstalledVirtualsRepository::do_has_package_named(const QualifiedPackageName & q) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesNameComparator()));
+
+ return p.first != p.second;
+}
+
+bool
+InstalledVirtualsRepository::do_has_category_named(const CategoryNamePart & c) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(c + PackageNamePart("dummy"), VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesCategoryComparator()));
+
+ return p.first != p.second;
+}
+
+bool
+InstalledVirtualsRepository::do_is_licence(const std::string &) const
+{
+ return false;
+}
+
+void
+InstalledVirtualsRepository::invalidate() const
+{
+ _imp->has_entries = false;
+ _imp->entries.clear();
+}
+
+void
+InstalledVirtualsRepository::do_uninstall(const QualifiedPackageName &, const VersionSpec &,
+ const InstallOptions &) const
+{
+}
+
diff --git a/paludis/repositories/virtuals/installed_virtuals_repository.hh b/paludis/repositories/virtuals/installed_virtuals_repository.hh
new file mode 100644
index 0000000..7404619
--- /dev/null
+++ b/paludis/repositories/virtuals/installed_virtuals_repository.hh
@@ -0,0 +1,94 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_INSTALLED_VIRTUALS_REPOSITORY_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_INSTALLED_VIRTUALS_REPOSITORY_HH 1
+
+#include <paludis/repository.hh>
+
+namespace paludis
+{
+ class InstalledVirtualsRepository :
+ public Repository,
+ public RepositoryInstalledInterface,
+ public RepositoryUninstallableInterface,
+ public RepositoryMaskInterface,
+ private PrivateImplementationPattern<InstalledVirtualsRepository>
+ {
+ private:
+ void need_entries() const;
+
+ protected:
+ virtual Contents::ConstPointer do_contents(
+ const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual bool do_query_repository_masks(const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual bool do_query_profile_masks(const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual VersionMetadata::ConstPointer do_version_metadata(
+ const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual bool do_has_version(const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual VersionSpecCollection::ConstPointer do_version_specs(
+ const QualifiedPackageName &) const;
+
+ virtual QualifiedPackageNameCollection::ConstPointer do_package_names(
+ const CategoryNamePart &) const;
+
+ virtual CategoryNamePartCollection::ConstPointer do_category_names() const;
+
+ virtual bool do_has_package_named(const QualifiedPackageName &) const;
+
+ virtual bool do_has_category_named(const CategoryNamePart &) const;
+
+ virtual bool do_is_licence(const std::string &) const;
+
+ virtual void do_uninstall(const QualifiedPackageName &, const VersionSpec &,
+ const InstallOptions &) const;
+
+ public:
+ InstalledVirtualsRepository(const Environment * const env);
+
+ virtual ~InstalledVirtualsRepository();
+
+ static CountedPtr<Repository> make_installed_virtuals_repository(
+ const Environment * const env,
+ const PackageDatabase * const db,
+ AssociativeCollection<std::string, std::string>::ConstPointer);
+
+ virtual void invalidate() const;
+
+ virtual bool can_be_favourite_repository() const
+ {
+ return false;
+ }
+ };
+
+ static const RepositoryMaker::RegisterMaker register_installed_virtuals_repository(
+ "installed_virtuals", &InstalledVirtualsRepository::make_installed_virtuals_repository);
+}
+
+#endif
diff --git a/paludis/repositories/virtuals/virtuals_repository.cc b/paludis/repositories/virtuals/virtuals_repository.cc
new file mode 100644
index 0000000..8b13d83
--- /dev/null
+++ b/paludis/repositories/virtuals/virtuals_repository.cc
@@ -0,0 +1,290 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "virtuals_repository.hh"
+#include <paludis/package_database.hh>
+#include <paludis/environment.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/fast_unique_copy.hh>
+#include <paludis/util/log.hh>
+#include "vr_entry.hh"
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<VirtualsRepository> :
+ InternalCounted<Implementation<VirtualsRepository> >
+ {
+ const Environment * const env;
+
+ mutable std::vector<VREntry> entries;
+ mutable bool has_entries;
+
+ Implementation(const Environment * const e) :
+ env(e),
+ has_entries(false)
+ {
+ }
+ };
+}
+
+VirtualsRepository::VirtualsRepository(const Environment * const env) :
+ Repository(RepositoryName("virtuals"), RepositoryCapabilities::create()
+ .installable_interface(this)
+ .mask_interface(this)
+ .installed_interface(0)
+ .use_interface(0)
+ .news_interface(0)
+ .sets_interface(0)
+ .syncable_interface(0)
+ .uninstallable_interface(0)
+ .mirrors_interface(0)
+ .environment_variable_interface(0)
+ .world_interface(0)
+ .provides_interface(0)
+ .virtuals_interface(0)),
+ PrivateImplementationPattern<VirtualsRepository>(
+ new Implementation<VirtualsRepository>(env))
+{
+ RepositoryInfoSection::Pointer config_info(new RepositoryInfoSection("Configuration information"));
+ config_info->add_kv("format", "virtuals");
+ _info->add_section(config_info);
+}
+
+VirtualsRepository::~VirtualsRepository()
+{
+}
+
+void
+VirtualsRepository::need_entries() const
+{
+ if (_imp->has_entries)
+ return;
+
+ Context context("When loading entries for virtuals repository:");
+
+ /* Populate our _imp->entries. We need to iterate over each repository in
+ * our env's package database, see if it has a virtuals interface, and if it
+ * does create an entry for each virtual package. */
+ for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
+ r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
+ {
+ if (! (*r)->virtuals_interface)
+ continue;
+
+ RepositoryVirtualsInterface::VirtualsCollection::ConstPointer pp(
+ (*r)->virtuals_interface->virtual_packages());
+
+ for (RepositoryVirtualsInterface::VirtualsCollection::Iterator p(
+ pp->begin()), p_end(pp->end()) ; p != p_end ; ++p)
+ {
+ VersionSpecCollection::ConstPointer vv((*r)->version_specs(p->provided_by_name));
+
+ /* following is debug, not warning, because of overlay style repos */
+ if (vv->empty())
+ Log::get_instance()->message(ll_debug, lc_context, "No packages matching '"
+ + stringify(p->provided_by_name) + "' for virtual '"
+ + stringify(p->virtual_name) + " ' in repository '"
+ + stringify((*r)->name()) + "'");
+
+ for (VersionSpecCollection::Iterator v(vv->begin()), v_end(vv->end()) ;
+ v != v_end ; ++v)
+ _imp->entries.push_back(VREntry::create()
+ .virtual_name(p->virtual_name)
+ .version(*v)
+ .provided_by_name(p->provided_by_name)
+ .provided_by_repository((*r)->name()));
+ }
+ }
+
+ _imp->has_entries = true;
+}
+
+CountedPtr<Repository>
+VirtualsRepository::make_virtuals_repository(
+ const Environment * const env,
+ const PackageDatabase * const,
+ AssociativeCollection<std::string, std::string>::ConstPointer)
+{
+ return CountedPtr<Repository>(new VirtualsRepository(env));
+}
+
+bool
+VirtualsRepository::do_query_repository_masks(const QualifiedPackageName &,
+ const VersionSpec &) const
+{
+ need_entries();
+
+ /// \todo
+ return false;
+}
+
+bool
+VirtualsRepository::do_query_profile_masks(const QualifiedPackageName &,
+ const VersionSpec &) const
+{
+ need_entries();
+
+ /// \todo
+ return false;
+}
+
+VersionMetadata::ConstPointer
+VirtualsRepository::do_version_metadata(
+ const QualifiedPackageName & q,
+ const VersionSpec & v) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, v, QualifiedPackageName("dummy/package"), RepositoryName("dummy_repository"))));
+
+ if (p.first == p.second)
+ throw NoSuchPackageError(stringify(PackageDatabaseEntry(q, v, name())));
+
+ return _imp->env->package_database()->fetch_repository(
+ p.first->provided_by_repository)->virtuals_interface->virtual_package_version_metadata(
+ RepositoryVirtualsEntry::create()
+ .virtual_name(p.first->virtual_name)
+ .provided_by_name(p.first->provided_by_name), v);
+}
+
+bool
+VirtualsRepository::do_has_version(const QualifiedPackageName & q,
+ const VersionSpec & v) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, v, QualifiedPackageName("dummy/package"), RepositoryName("dummy_repository"))));
+
+ return p.first != p.second;
+}
+
+VersionSpecCollection::ConstPointer
+VirtualsRepository::do_version_specs(const QualifiedPackageName & q) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesNameComparator()));
+
+ VersionSpecCollection::Pointer result(new VersionSpecCollection::Concrete);
+ for ( ; p.first != p.second ; ++p.first)
+ result->insert(p.first->version);
+
+ return result;
+}
+
+QualifiedPackageNameCollection::ConstPointer
+VirtualsRepository::do_package_names(const CategoryNamePart & c) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(c + PackageNamePart("dummy"), VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesCategoryComparator()));
+
+
+ QualifiedPackageNameCollection::Pointer result(new QualifiedPackageNameCollection::Concrete);
+#if 0
+ /// \todo: in theory, this can be a lot faster
+ for ( ; p.first != p.second ; ++p.first)
+ result->insert(p.first->virtual_name);
+#else
+ fast_unique_copy(p.first, p.second,
+ transform_inserter(result->inserter(), EntriesNameExtractor()),
+ EntriesNameComparator());
+#endif
+
+ return result;
+}
+
+CategoryNamePartCollection::ConstPointer
+VirtualsRepository::do_category_names() const
+{
+ need_entries();
+
+ CategoryNamePartCollection::Pointer result(new CategoryNamePartCollection::Concrete);
+#if 0
+ /// \todo: in theory, this can be a lot lot lot faster
+ for (std::vector<VREntry>::const_iterator p(_imp->entries.begin()), p_end(_imp->entries.end()) ;
+ p != p_end ; ++p)
+ result->insert(p->virtual_name.category);
+#else
+ fast_unique_copy(_imp->entries.begin(), _imp->entries.end(),
+ transform_inserter(result->inserter(), EntriesCategoryExtractor()),
+ EntriesCategoryComparator());
+#endif
+
+ return result;
+}
+
+bool
+VirtualsRepository::do_has_package_named(const QualifiedPackageName & q) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(q, VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesNameComparator()));
+
+ return p.first != p.second;
+}
+
+bool
+VirtualsRepository::do_has_category_named(const CategoryNamePart & c) const
+{
+ need_entries();
+
+ std::pair<std::vector<VREntry>::const_iterator, std::vector<VREntry>::const_iterator> p(
+ std::equal_range(_imp->entries.begin(), _imp->entries.end(),
+ VREntry(c + PackageNamePart("dummy"), VersionSpec("0"), QualifiedPackageName("dummy/package"),
+ RepositoryName("dummy_repository")), EntriesCategoryComparator()));
+
+ return p.first != p.second;
+}
+
+bool
+VirtualsRepository::do_is_licence(const std::string &) const
+{
+ return false;
+}
+
+void
+VirtualsRepository::invalidate() const
+{
+ _imp->has_entries = false;
+ _imp->entries.clear();
+}
+
+void
+VirtualsRepository::do_install(const QualifiedPackageName &, const VersionSpec &,
+ const InstallOptions &) const
+{
+}
+
diff --git a/paludis/repositories/virtuals/virtuals_repository.hh b/paludis/repositories/virtuals/virtuals_repository.hh
new file mode 100644
index 0000000..b686ec1
--- /dev/null
+++ b/paludis/repositories/virtuals/virtuals_repository.hh
@@ -0,0 +1,90 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_VIRTUALS_REPOSITORY_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_VIRTUALS_REPOSITORY_HH 1
+
+#include <paludis/repository.hh>
+
+namespace paludis
+{
+ class VirtualsRepository :
+ public Repository,
+ public RepositoryInstallableInterface,
+ public RepositoryMaskInterface,
+ private PrivateImplementationPattern<VirtualsRepository>
+ {
+ private:
+ void need_entries() const;
+
+ protected:
+ virtual bool do_query_repository_masks(const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual bool do_query_profile_masks(const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual VersionMetadata::ConstPointer do_version_metadata(
+ const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual bool do_has_version(const QualifiedPackageName &,
+ const VersionSpec &) const;
+
+ virtual VersionSpecCollection::ConstPointer do_version_specs(
+ const QualifiedPackageName &) const;
+
+ virtual QualifiedPackageNameCollection::ConstPointer do_package_names(
+ const CategoryNamePart &) const;
+
+ virtual CategoryNamePartCollection::ConstPointer do_category_names() const;
+
+ virtual bool do_has_package_named(const QualifiedPackageName &) const;
+
+ virtual bool do_has_category_named(const CategoryNamePart &) const;
+
+ virtual bool do_is_licence(const std::string &) const;
+
+ virtual void do_install(const QualifiedPackageName &, const VersionSpec &,
+ const InstallOptions &) const;
+
+ public:
+ VirtualsRepository(const Environment * const env);
+
+ virtual ~VirtualsRepository();
+
+ static CountedPtr<Repository> make_virtuals_repository(
+ const Environment * const env,
+ const PackageDatabase * const db,
+ AssociativeCollection<std::string, std::string>::ConstPointer);
+
+ virtual void invalidate() const;
+
+ virtual bool can_be_favourite_repository() const
+ {
+ return false;
+ }
+
+ };
+
+ static const RepositoryMaker::RegisterMaker register_virtuals_repository(
+ "virtuals", &VirtualsRepository::make_virtuals_repository);
+}
+
+#endif
diff --git a/paludis/repositories/virtuals/vr_entry.cc b/paludis/repositories/virtuals/vr_entry.cc
new file mode 100644
index 0000000..07dac71
--- /dev/null
+++ b/paludis/repositories/virtuals/vr_entry.cc
@@ -0,0 +1,26 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "vr_entry.hh"
+#include <paludis/util/compare.hh>
+
+using namespace paludis;
+
+#include <paludis/repositories/virtuals/vr_entry-sr.cc>
+
diff --git a/paludis/repositories/virtuals/vr_entry.hh b/paludis/repositories/virtuals/vr_entry.hh
new file mode 100644
index 0000000..e6cac7d
--- /dev/null
+++ b/paludis/repositories/virtuals/vr_entry.hh
@@ -0,0 +1,120 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_VR_ENTRY_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_VR_ENTRY_HH 1
+
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/package_database.hh>
+#include <paludis/environment.hh>
+
+namespace paludis
+{
+
+#include <paludis/repositories/virtuals/vr_entry-sr.hh>
+
+ /**
+ * Sort ordering for _imp->entries for an InstalledVirtualsRepository.
+ */
+ struct EntriesComparator
+ {
+ PackageDatabase::ConstPointer const db;
+
+ EntriesComparator(PackageDatabase::ConstPointer const d) :
+ db(d)
+ {
+ }
+
+ bool
+ operator() (const VREntry & a, const VREntry & b) const
+ {
+ switch (a.compare(b))
+ {
+ case -1:
+ return true;
+
+ case 1:
+ return false;
+ }
+
+ if (a.provided_by_repository != b.provided_by_repository)
+ {
+ // not a bug
+ if (a.provided_by_repository == db->better_repository(a.provided_by_repository,
+ b.provided_by_repository))
+ return true;
+ return false;
+ }
+
+ return a.provided_by_name > b.provided_by_name; // not a bug either
+ }
+ };
+
+ /**
+ * Comparison on name only for an VREntry.
+ */
+ struct EntriesNameComparator
+ {
+ bool
+ operator() (const VREntry & a, const VREntry & b) const
+ {
+ return a.virtual_name < b.virtual_name;
+ }
+ };
+
+ /**
+ * Extract only the name for an VREntry.
+ */
+ struct EntriesNameExtractor
+ {
+ QualifiedPackageName
+ operator() (const VREntry & a) const
+ {
+ return a.virtual_name;
+ }
+ };
+
+ /**
+ * Comparison on category name only for an VREntry.
+ */
+ struct EntriesCategoryComparator
+ {
+ bool
+ operator() (const VREntry & a, const VREntry & b) const
+ {
+ return a.virtual_name.category < b.virtual_name.category;
+ }
+ };
+
+ /**
+ * Extract only the category name for an VREntry.
+ */
+ struct EntriesCategoryExtractor
+ {
+ CategoryNamePart
+ operator() (const VREntry & a) const
+ {
+ return a.virtual_name.category;
+ }
+ };
+
+}
+
+#endif
diff --git a/paludis/repositories/virtuals/vr_entry.sr b/paludis/repositories/virtuals/vr_entry.sr
new file mode 100644
index 0000000..eba905f
--- /dev/null
+++ b/paludis/repositories/virtuals/vr_entry.sr
@@ -0,0 +1,16 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_VREntry()
+{
+ key virtual_name QualifiedPackageName
+ key version VersionSpec
+ key provided_by_name QualifiedPackageName
+ key provided_by_repository RepositoryName
+
+ comparison_operators all virtual_name version
+
+ allow_named_args
+}
+
+
diff --git a/paludis/repository.cc b/paludis/repository.cc
index 4b63370..bd74f08 100644
--- a/paludis/repository.cc
+++ b/paludis/repository.cc
@@ -18,6 +18,7 @@
*/
#include <paludis/repository.hh>
+#include <paludis/util/compare.hh>
#include <map>
#include <list>
#include <ctype.h>
diff --git a/paludis/repository.hh b/paludis/repository.hh
index 48b8823..939af7a 100644
--- a/paludis/repository.hh
+++ b/paludis/repository.hh
@@ -58,6 +58,8 @@ namespace paludis
class RepositoryWorldInterface;
class RepositoryEnvironmentVariableInterface;
class RepositoryMirrorsInterface;
+ class RepositoryProvidesInterface;
+ class RepositoryVirtualsInterface;
#include <paludis/repository-sr.hh>
@@ -306,19 +308,12 @@ namespace paludis
virtual void invalidate() const = 0;
/**
- * Our provide map iterator type.
+ * Are we allowed to be favourite repository?
*/
- typedef std::map<QualifiedPackageName, QualifiedPackageName>::const_iterator ProvideMapIterator;
-
- /**
- * Start of our provide map.
- */
- virtual ProvideMapIterator begin_provide_map() const = 0;
-
- /**
- * Past the end of our provide map.
- */
- virtual ProvideMapIterator end_provide_map() const = 0;
+ virtual bool can_be_favourite_repository() const
+ {
+ return true;
+ }
};
/**
@@ -711,6 +706,44 @@ namespace paludis
};
/**
+ * Interface for repositories that define virtuals.
+ *
+ * \see Repository
+ * \ingroup grprepository
+ */
+ class RepositoryVirtualsInterface
+ {
+ public:
+ typedef SortedCollection<RepositoryVirtualsEntry> VirtualsCollection;
+
+ virtual VirtualsCollection::ConstPointer virtual_packages() const = 0;
+
+ virtual VersionMetadata::ConstPointer virtual_package_version_metadata(
+ const RepositoryVirtualsEntry &, const VersionSpec & v) const = 0;
+
+ virtual ~RepositoryVirtualsInterface() { }
+ };
+
+ /**
+ * Interface for repositories that provide packages.
+ *
+ * \see Repository
+ * \ingroup grprepository
+ */
+ class RepositoryProvidesInterface
+ {
+ public:
+ typedef SortedCollection<RepositoryProvidesEntry> ProvidesCollection;
+
+ virtual ProvidesCollection::ConstPointer provided_packages() const = 0;
+
+ virtual VersionMetadata::ConstPointer provided_package_version_metadata(
+ const RepositoryProvidesEntry &) const = 0;
+
+ virtual ~RepositoryProvidesInterface() { }
+ };
+
+ /**
* Thrown if a repository of the specified type does not exist.
*
* \ingroup grpexceptions
diff --git a/paludis/repository.sr b/paludis/repository.sr
index 49e336f..b3ca75d 100644
--- a/paludis/repository.sr
+++ b/paludis/repository.sr
@@ -43,6 +43,8 @@ make_class_RepositoryCapabilities()
key world_interface "RepositoryWorldInterface *"
key mirrors_interface "RepositoryMirrorsInterface *"
key environment_variable_interface "RepositoryEnvironmentVariableInterface *"
+ key provides_interface "RepositoryProvidesInterface *"
+ key virtuals_interface "RepositoryVirtualsInterface *"
doxygen_comment << "END"
/**
@@ -56,4 +58,22 @@ END
allow_named_args
}
+make_class_RepositoryProvidesEntry()
+{
+ key virtual_name QualifiedPackageName
+ key version VersionSpec
+ key provided_by_name QualifiedPackageName
+
+ allow_named_args
+ comparison_operators all all
+}
+
+make_class_RepositoryVirtualsEntry()
+{
+ key virtual_name QualifiedPackageName
+ key provided_by_name QualifiedPackageName
+
+ allow_named_args
+ comparison_operators all all
+}
diff --git a/paludis/repository_config_entry.sr b/paludis/repository_config_entry.sr
index 2224f0e..274e9be 100644
--- a/paludis/repository_config_entry.sr
+++ b/paludis/repository_config_entry.sr
@@ -4,7 +4,7 @@
make_class_RepositoryConfigEntry()
{
key format std::string
- key importance unsigned
+ key importance int
key keys "AssociativeCollection<std::string, std::string>::Pointer"
doxygen_comment << "END"
diff --git a/paludis/util/fast_unique_copy.hh b/paludis/util/fast_unique_copy.hh
new file mode 100644
index 0000000..22c924f
--- /dev/null
+++ b/paludis/util/fast_unique_copy.hh
@@ -0,0 +1,84 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_FAST_UNIQUE_COPY_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_VIRTUALS_FAST_UNIQUE_COPY_HH 1
+
+#include <paludis/util/iterator.hh>
+#include <functional>
+
+namespace paludis
+{
+ /**
+ * For use by fast_unique_copy only.
+ */
+ namespace fast_unique_copy_internals
+ {
+ /**
+ * For use by fast_unique_copy only.
+ */
+ template <typename I_, typename O_, typename C_>
+ void
+ real_fast_unique_copy(const I_ & start, const I_ & end, const I_ & full_end, O_ out,
+ const C_ & comp, const I_ & mbgt)
+ {
+ if (start != end)
+ {
+ // if our final item is less than or equal to mbgt, there're no
+ // matches in this block
+ if ((mbgt != full_end) && ((comp(*previous(end), *mbgt)) || (! comp(*mbgt, *previous(end)))))
+ return;
+
+ // if our first item is equal to our last item, we have exactly
+ // one unique item in this sequence
+ if ((! comp(*start, *previous(end))) && (! comp(*previous(end), *start)))
+ *out++ = *start;
+ else
+ {
+ I_ mid = start + (std::distance(start, end) >> 1);
+ real_fast_unique_copy(start, mid, full_end, out, comp, mbgt);
+ real_fast_unique_copy(mid, end, full_end, out, comp, previous(mid));
+ }
+ }
+ }
+ }
+
+ /**
+ * Extract unique elements from a sorted range of random access iterators.
+ */
+ template <typename I_, typename O_>
+ void
+ fast_unique_copy(const I_ & start, const I_ & end, O_ out)
+ {
+ fast_unique_copy_internals::real_fast_unique_copy(start, end, end, out,
+ std::less<typename std::iterator_traits<I_>::value_type>(), end);
+ }
+
+ /**
+ * Extract unique elements from a sorted range of random access iterators.
+ */
+ template <typename I_, typename O_, typename C_>
+ void
+ fast_unique_copy(const I_ & start, const I_ & end, O_ out, const C_ & comp)
+ {
+ fast_unique_copy_internals::real_fast_unique_copy(start, end, end, out, comp, end);
+ }
+}
+
+#endif
diff --git a/paludis/util/fast_unique_copy_TEST.cc b/paludis/util/fast_unique_copy_TEST.cc
new file mode 100644
index 0000000..fa7a0f2
--- /dev/null
+++ b/paludis/util/fast_unique_copy_TEST.cc
@@ -0,0 +1,121 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "fast_unique_copy.hh"
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+#include <paludis/util/join.hh>
+#include <vector>
+
+using namespace test;
+using namespace paludis;
+
+namespace test_cases
+{
+ struct FastUniqueCopySimpleSequenceTest : TestCase
+ {
+ FastUniqueCopySimpleSequenceTest() : TestCase("fast_unique_copy simple sequence") { }
+
+ void run()
+ {
+ for (unsigned sz = 0 ; sz < 20 ; ++sz)
+ {
+ TestMessageSuffix s("sz=" + stringify(sz));
+ std::vector<unsigned> v;
+ for (unsigned x = 0 ; x < sz ; ++x)
+ v.push_back(x);
+
+ std::vector<unsigned> r;
+ fast_unique_copy(v.begin(), v.end(), std::back_inserter(r), std::less<int>());
+
+ TestMessageSuffix vs("v=" + join(v.begin(), v.end(), ","));
+ TestMessageSuffix rs("r=" + join(r.begin(), r.end(), ","));
+
+ TEST_CHECK_EQUAL(r.size(), sz);
+ for (unsigned x = 0 ; x < sz ; ++x)
+ TEST_CHECK_EQUAL(r[x], x);
+ }
+ }
+
+ } test_fast_unique_copy_simple_sequence;
+
+ struct FastUniqueCopyRepeatedElementTest : TestCase
+ {
+ FastUniqueCopyRepeatedElementTest() : TestCase("fast_unique_copy single repeated element") { }
+
+ void run()
+ {
+ for (unsigned sz = 0 ; sz < 20 ; ++sz)
+ {
+ TestMessageSuffix s("sz=" + stringify(sz));
+ std::vector<unsigned> v;
+ for (unsigned x = 0 ; x < sz ; ++x)
+ v.push_back(42);
+
+ std::vector<unsigned> r;
+ fast_unique_copy(v.begin(), v.end(), std::back_inserter(r));
+
+ TestMessageSuffix vs("v=" + join(v.begin(), v.end(), ","));
+ TestMessageSuffix rs("r=" + join(r.begin(), r.end(), ","));
+
+ if (sz == 0)
+ TEST_CHECK_EQUAL(r.size(), 0);
+ else
+ {
+ TEST_CHECK_EQUAL(r.size(), 1);
+ TEST_CHECK_EQUAL(r[0], 42);
+ }
+ }
+ }
+
+ } test_fast_unique_copy_repeated_element;
+
+ struct FastUniqueCopyNxNTest : TestCase
+ {
+ FastUniqueCopyNxNTest() : TestCase("fast_unique_copy nxn") { }
+
+ void run()
+ {
+ for (unsigned sz = 0 ; sz < 20 ; ++sz)
+ {
+ TestMessageSuffix s("sz=" + stringify(sz));
+ std::vector<unsigned> v;
+ for (unsigned x = 0 ; x < sz ; ++x)
+ for (unsigned y = 0 ; y < x ; ++y)
+ v.push_back(x);
+
+ std::vector<unsigned> r;
+ fast_unique_copy(v.begin(), v.end(), std::back_inserter(r));
+
+ TestMessageSuffix vs("v=" + join(v.begin(), v.end(), ","));
+ TestMessageSuffix rs("r=" + join(r.begin(), r.end(), ","));
+ if (sz == 0)
+ TEST_CHECK_EQUAL(r.size(), 0);
+ else
+ {
+ TEST_CHECK_EQUAL(r.size(), sz - 1);
+ for (unsigned x = 0 ; x < sz - 1 ; ++x)
+ TEST_CHECK_EQUAL(r[x], x + 1);
+ }
+ }
+ }
+
+ } test_fast_unique_copy_nxn;
+}
+
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index dea1b6f..0f2fdeb 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -17,6 +17,7 @@ add(`counted_ptr', `hh', `cc', `test')
add(`destringify', `hh', `cc', `test')
add(`dir_iterator', `hh', `cc', `test', `testscript')
add(`exception', `hh', `cc')
+add(`fast_unique_copy', `hh', `test')
add(`fd_output_stream', `hh')
add(`fs_entry', `hh', `cc', `test', `testscript')
add(`iterator', `hh', `test')
diff --git a/paludis/version_metadata.cc b/paludis/version_metadata.cc
index 5764d6e..ffa8420 100644
--- a/paludis/version_metadata.cc
+++ b/paludis/version_metadata.cc
@@ -57,7 +57,7 @@ VersionMetadataDeps::VersionMetadataDeps(const ParserFunction & p) :
}
VersionMetadata::CRAN::CRAN(ParserFunction f) :
- VersionMetadata(f, &_c, 0, 0),
+ VersionMetadata(f, &_c, 0, 0, 0),
_c(CRANVersionMetadata::create()
.keywords("")
.package("")
@@ -67,13 +67,13 @@ VersionMetadata::CRAN::CRAN(ParserFunction f) :
}
VersionMetadata::Ebuild::Ebuild(ParserFunction f) :
- VersionMetadata(f, 0, &_e, 0),
+ VersionMetadata(f, 0, &_e, 0, 0),
_e()
{
}
VersionMetadata::Ebin::Ebin(ParserFunction f) :
- VersionMetadata(f, 0, &_e, &_eb),
+ VersionMetadata(f, 0, &_e, &_eb, 0),
_e(),
_eb()
{
@@ -93,14 +93,16 @@ VersionMetadata::VersionMetadata(ParserFunction p) :
.eapi("")),
_cran_if(0),
_ebuild_if(0),
- _ebin_if(0)
+ _ebin_if(0),
+ _virtual_if(0)
{
}
VersionMetadata::VersionMetadata(ParserFunction p,
CRANVersionMetadata * cran_if,
EbuildVersionMetadata * ebuild_if,
- EbinVersionMetadata * ebin_if) :
+ EbinVersionMetadata * ebin_if,
+ VirtualMetadata * virtual_if) :
VersionMetadataBase(VersionMetadataBase::create()
.slot(SlotName("unset"))
.deps(VersionMetadataDeps(p))
@@ -110,7 +112,8 @@ VersionMetadata::VersionMetadata(ParserFunction p,
.eapi("")),
_cran_if(cran_if),
_ebuild_if(ebuild_if),
- _ebin_if(ebin_if)
+ _ebin_if(ebin_if),
+ _virtual_if(virtual_if)
{
}
@@ -120,7 +123,6 @@ EbuildVersionMetadata::EbuildVersionMetadata() :
restrict_string(""),
keywords(""),
iuse(""),
- virtual_for(""),
inherited("")
{
}
@@ -144,3 +146,10 @@ VersionMetadata::license() const
return PortageDepParser::parse(license_string, PortageDepParserPolicy<PlainTextDepAtom,
true>::get_instance());
}
+
+VersionMetadata::Virtual::Virtual(ParserFunction p, const PackageDatabaseEntry & e) :
+ VersionMetadata(p, 0, 0, 0, &_v),
+ _v(e)
+{
+}
+
diff --git a/paludis/version_metadata.hh b/paludis/version_metadata.hh
index b5ab0bc..bbca832 100644
--- a/paludis/version_metadata.hh
+++ b/paludis/version_metadata.hh
@@ -25,6 +25,7 @@
#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/sr.hh>
#include <paludis/dep_atom.hh>
+#include <paludis/package_database_entry.hh>
#include <string>
/** \file
@@ -58,6 +59,7 @@ namespace paludis
CRANVersionMetadata * _cran_if;
EbuildVersionMetadata * _ebuild_if;
EbinVersionMetadata * _ebin_if;
+ VirtualMetadata * _virtual_if;
protected:
/**
@@ -65,7 +67,8 @@ namespace paludis
*/
VersionMetadata(ParserFunction, CRANVersionMetadata * cran_if,
EbuildVersionMetadata * ebuild_if,
- EbinVersionMetadata * ebin_if);
+ EbinVersionMetadata * ebin_if,
+ VirtualMetadata * virtual_if);
public:
/**
@@ -96,7 +99,6 @@ namespace paludis
return _cran_if;
}
-
class CRAN;
/**
@@ -137,11 +139,32 @@ namespace paludis
return _ebin_if;
}
+ class Ebin;
+
+ /**
+ * Fetch our virtual interface, or 0.
+ */
+ VirtualMetadata *
+ get_virtual_interface()
+ {
+ return _virtual_if;
+ }
+
+ /**
+ * Fetch our virtual interface, or 0.
+ */
+ const VirtualMetadata *
+ get_virtual_interface() const
+ {
+ return _virtual_if;
+ }
+
+ class Virtual;
+
/**
* Fetch our licence, as a dep atom structure.
*/
DepAtom::ConstPointer license() const;
- class Ebin;
};
/**
@@ -231,6 +254,35 @@ namespace paludis
*/
typedef CountedPtr<const VersionMetadata::Ebin, count_policy::InternalCountTag> ConstPointer;
};
+
+ /**
+ * VersionMetadata subclass, for virtuals.
+ *
+ * \ingroup grpversions
+ * \see VersionMetadata
+ */
+ class VersionMetadata::Virtual :
+ public VersionMetadata
+ {
+ private:
+ VirtualMetadata _v;
+
+ public:
+ /**
+ * Constructor.
+ */
+ Virtual(ParserFunction, const PackageDatabaseEntry &);
+
+ /**
+ * Pointer to us.
+ */
+ typedef CountedPtr<VersionMetadata::Virtual, count_policy::InternalCountTag> Pointer;
+
+ /**
+ * Const pointer to us.
+ */
+ typedef CountedPtr<const VersionMetadata::Virtual, count_policy::InternalCountTag> ConstPointer;
+ };
}
#endif
diff --git a/paludis/version_metadata.sr b/paludis/version_metadata.sr
index 7f6f25a..f224767 100644
--- a/paludis/version_metadata.sr
+++ b/paludis/version_metadata.sr
@@ -49,7 +49,6 @@ make_class_EbuildVersionMetadata()
key restrict_string std::string
key keywords std::string
key iuse std::string
- key virtual_for std::string
key inherited std::string
extra_constructors <<END
@@ -86,3 +85,8 @@ make_class_EbinVersionMetadata()
END
}
+make_class_VirtualMetadata()
+{
+ key virtual_for PackageDatabaseEntry
+}
+
diff --git a/src/paludis/query.cc b/src/paludis/query.cc
index 1c38eae..5dfe5d6 100644
--- a/src/paludis/query.cc
+++ b/src/paludis/query.cc
@@ -154,6 +154,9 @@ void do_one_query(
case p::mr_license:
reasons.append("L");
break;
+ case p::mr_by_association:
+ reasons.append("A");
+ break;
case p::last_mr:
break;
}
@@ -219,8 +222,6 @@ void do_one_query(
" " << metadata->get_ebuild_interface()->restrict_string << endl;
cout << " " << std::setw(22) << std::left << "SRC_URI:" << std::setw(0) <<
" " << metadata->get_ebuild_interface()->src_uri << endl;
- cout << " " << std::setw(22) << std::left << "VIRTUAL:" << std::setw(0) <<
- " " << metadata->get_ebuild_interface()->virtual_for << endl;
}
if (metadata->get_ebin_interface())
@@ -277,11 +278,6 @@ void do_one_query(
}
if (metadata->get_ebuild_interface() && ! metadata->get_ebuild_interface()->
- virtual_for.empty())
- cout << " " << std::setw(22) << std::left << "Virtual for:" << std::setw(0) <<
- " " << metadata->get_ebuild_interface()->virtual_for << endl;
-
- if (metadata->get_ebuild_interface() && ! metadata->get_ebuild_interface()->
provide_string.empty())
cout << " " << std::setw(22) << std::left << "Provides:" << std::setw(0) <<
" " << metadata->get_ebuild_interface()->provide_string << endl;
@@ -376,6 +372,9 @@ int do_query()
case p::mr_license:
cout << "* " << colour(cl_masked, "L") << ": licence";
break;
+ case p::mr_by_association:
+ cout << "* " << colour(cl_masked, "A") << ": by association";
+ break;
case p::last_mr:
break;