aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2007-12-31 14:13:04 +0000
committerAvatar David Leverton <levertond@googlemail.com> 2007-12-31 14:13:04 +0000
commit819f0f92f1b3c02f8bc52b0b02ddd08c198d4dc4 (patch)
tree08f763309159127c10d8ed16b64f91d7f1e693eb
parent716dfad8ca27d774b1b07b9a6783b2afe8a960c6 (diff)
downloadpaludis-819f0f92f1b3c02f8bc52b0b02ddd08c198d4dc4.tar.gz
paludis-819f0f92f1b3c02f8bc52b0b02ddd08c198d4dc4.tar.xz
Add some more UseRequirement variants, and change the syntax of the old ones.
-rw-r--r--doc/api/cplusplus/examples/example_dep_spec.cc24
-rw-r--r--paludis/dep_list_TEST.cc388
-rw-r--r--paludis/dep_spec.cc24
-rw-r--r--paludis/dep_spec_TEST.cc10
-rw-r--r--paludis/environments/test/test_environment.cc5
-rw-r--r--paludis/match_package.cc45
-rw-r--r--paludis/repositories/e/package_dep_spec.cc48
-rw-r--r--paludis/repositories/fake/fake_package_id.cc71
-rw-r--r--paludis/repositories/fake/fake_package_id.hh3
-rw-r--r--paludis/use_requirements-fwd.hh4
-rw-r--r--paludis/use_requirements.cc116
-rw-r--r--paludis/use_requirements.hh174
-rw-r--r--python/use_requirements.cc89
-rwxr-xr-xpython/use_requirements_TEST.py33
14 files changed, 883 insertions, 151 deletions
diff --git a/doc/api/cplusplus/examples/example_dep_spec.cc b/doc/api/cplusplus/examples/example_dep_spec.cc
index 9be91eb..c819d7f 100644
--- a/doc/api/cplusplus/examples/example_dep_spec.cc
+++ b/doc/api/cplusplus/examples/example_dep_spec.cc
@@ -51,14 +51,34 @@ namespace
s << "[!" << r.flag() << "]";
}
- void visit(const EqualUseRequirement & r)
+ void visit(const IfMineThenUseRequirement & r)
{
s << "[" << r.flag() << "?] (using '" << *r.package_id() << "')";
}
+ void visit(const IfNotMineThenUseRequirement & r)
+ {
+ s << "[" << r.flag() << "!?] (using '" << *r.package_id() << "')";
+ }
+
+ void visit(const IfMineThenNotUseRequirement & r)
+ {
+ s << "[-" << r.flag() << "?] (using '" << *r.package_id() << "')";
+ }
+
+ void visit(const IfNotMineThenNotUseRequirement & r)
+ {
+ s << "[-" << r.flag() << "!?] (using '" << *r.package_id() << "')";
+ }
+
+ void visit(const EqualUseRequirement & r)
+ {
+ s << "[" << r.flag() << "=] (using '" << *r.package_id() << "')";
+ }
+
void visit(const NotEqualUseRequirement & r)
{
- s << "[!" << r.flag() << "?] (using '" << *r.package_id() << "')";
+ s << "[" << r.flag() << "!=] (using '" << *r.package_id() << "')";
}
};
}
diff --git a/paludis/dep_list_TEST.cc b/paludis/dep_list_TEST.cc
index d859caf..945afa8 100644
--- a/paludis/dep_list_TEST.cc
+++ b/paludis/dep_list_TEST.cc
@@ -1391,6 +1391,394 @@ namespace test_cases
} test_dep_list_65;
/**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase66 : DepListTestCase<66>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/enabled[pkgname?] )");
+ repo->add_version("cat2", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat3", "disabled", "1")->build_dependencies_key()->set_from_string("( cat4/enabled[pkgname?] )");
+ repo->add_version("cat4", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat5", "disabled", "1")->build_dependencies_key()->set_from_string("( cat6/disabled[pkgname?] )");
+ repo->add_version("cat6", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat", "all", "1")->build_dependencies_key()->set_from_string("( cat5/disabled cat3/disabled cat1/enabled )");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/all";
+ expected.push_back("cat6/disabled-1:0::repo");
+ expected.push_back("cat5/disabled-1:0::repo");
+ expected.push_back("cat4/enabled-1:0::repo");
+ expected.push_back("cat3/disabled-1:0::repo");
+ expected.push_back("cat2/enabled-1:0::repo");
+ expected.push_back("cat1/enabled-1:0::repo");
+ expected.push_back("cat/all-1:0::repo");
+ }
+ } test_dep_list_66;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase67 : DepListTestCase<67>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[pkgname?] )");
+ repo->add_version("cat2", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/enabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_67;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase68 : DepListTestCase<68>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "disabled", "1")->build_dependencies_key()->set_from_string("( cat2/enabled[pkgname!?] )");
+ repo->add_version("cat2", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat3", "enabled", "1")->build_dependencies_key()->set_from_string("( cat4/enabled[pkgname!?] )");
+ repo->add_version("cat4", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat5", "enabled", "1")->build_dependencies_key()->set_from_string("( cat6/disabled[pkgname!?] )");
+ repo->add_version("cat6", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat", "all", "1")->build_dependencies_key()->set_from_string("( cat5/enabled cat3/enabled cat1/disabled )");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/all";
+ expected.push_back("cat6/disabled-1:0::repo");
+ expected.push_back("cat5/enabled-1:0::repo");
+ expected.push_back("cat4/enabled-1:0::repo");
+ expected.push_back("cat3/enabled-1:0::repo");
+ expected.push_back("cat2/enabled-1:0::repo");
+ expected.push_back("cat1/disabled-1:0::repo");
+ expected.push_back("cat/all-1:0::repo");
+ }
+ } test_dep_list_68;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase69 : DepListTestCase<69>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "disabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[pkgname!?] )");
+ repo->add_version("cat2", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/disabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_69;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase70 : DepListTestCase<70>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[-pkgname?] )");
+ repo->add_version("cat2", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat3", "disabled", "1")->build_dependencies_key()->set_from_string("( cat4/enabled[-pkgname?] )");
+ repo->add_version("cat4", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat5", "disabled", "1")->build_dependencies_key()->set_from_string("( cat6/disabled[-pkgname?] )");
+ repo->add_version("cat6", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat", "all", "1")->build_dependencies_key()->set_from_string("( cat5/disabled cat3/disabled cat1/enabled )");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/all";
+ expected.push_back("cat6/disabled-1:0::repo");
+ expected.push_back("cat5/disabled-1:0::repo");
+ expected.push_back("cat4/enabled-1:0::repo");
+ expected.push_back("cat3/disabled-1:0::repo");
+ expected.push_back("cat2/disabled-1:0::repo");
+ expected.push_back("cat1/enabled-1:0::repo");
+ expected.push_back("cat/all-1:0::repo");
+ }
+ } test_dep_list_70;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase71 : DepListTestCase<71>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/enabled[-pkgname?] )");
+ repo->add_version("cat2", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/enabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_71;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase72 : DepListTestCase<72>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "disabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[-pkgname!?] )");
+ repo->add_version("cat2", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat3", "enabled", "1")->build_dependencies_key()->set_from_string("( cat4/enabled[-pkgname!?] )");
+ repo->add_version("cat4", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat5", "enabled", "1")->build_dependencies_key()->set_from_string("( cat6/disabled[-pkgname!?] )");
+ repo->add_version("cat6", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat", "all", "1")->build_dependencies_key()->set_from_string("( cat5/enabled cat3/enabled cat1/disabled )");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/all";
+ expected.push_back("cat6/disabled-1:0::repo");
+ expected.push_back("cat5/enabled-1:0::repo");
+ expected.push_back("cat4/enabled-1:0::repo");
+ expected.push_back("cat3/enabled-1:0::repo");
+ expected.push_back("cat2/disabled-1:0::repo");
+ expected.push_back("cat1/disabled-1:0::repo");
+ expected.push_back("cat/all-1:0::repo");
+ }
+ } test_dep_list_72;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase73 : DepListTestCase<73>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "disabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[-pkgname!?] )");
+ repo->add_version("cat2", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/disabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_73;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase74 : DepListTestCase<74>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/enabled[pkgname=] )");
+ repo->add_version("cat2", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat3", "disabled", "1")->build_dependencies_key()->set_from_string("( cat4/disabled[pkgname=] )");
+ repo->add_version("cat4", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat", "all", "1")->build_dependencies_key()->set_from_string("( cat3/disabled cat1/enabled )");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/all";
+ expected.push_back("cat4/disabled-1:0::repo");
+ expected.push_back("cat3/disabled-1:0::repo");
+ expected.push_back("cat2/enabled-1:0::repo");
+ expected.push_back("cat1/enabled-1:0::repo");
+ expected.push_back("cat/all-1:0::repo");
+ }
+ } test_dep_list_74;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase75 : DepListTestCase<75>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[pkgname=] )");
+ repo->add_version("cat2", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/enabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_75;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase76 : DepListTestCase<76>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "disabled", "1")->build_dependencies_key()->set_from_string("( cat2/enabled[pkgname=] )");
+ repo->add_version("cat2", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/disabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_76;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase77 : DepListTestCase<77>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[pkgname!=] )");
+ repo->add_version("cat2", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat3", "disabled", "1")->build_dependencies_key()->set_from_string("( cat4/enabled[pkgname!=] )");
+ repo->add_version("cat4", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ repo->add_version("cat", "all", "1")->build_dependencies_key()->set_from_string("( cat3/disabled cat1/enabled )");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/all";
+ expected.push_back("cat4/enabled-1:0::repo");
+ expected.push_back("cat3/disabled-1:0::repo");
+ expected.push_back("cat2/disabled-1:0::repo");
+ expected.push_back("cat1/enabled-1:0::repo");
+ expected.push_back("cat/all-1:0::repo");
+ }
+ } test_dep_list_77;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase78 : DepListTestCase<78>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "enabled", "1")->build_dependencies_key()->set_from_string("( cat2/disabled[pkgname!=] )");
+ repo->add_version("cat2", "enabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/enabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_78;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase79 : DepListTestCase<79>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat1", "disabled", "1")->build_dependencies_key()->set_from_string("( cat2/enabled[pkgname!=] )");
+ repo->add_version("cat2", "disabled", "1")->iuse_key()->set_from_string("ebuild", iuse_pm_permissive);
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat1/disabled";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PackageDepSpec(parse_user_package_dep_spec(merge_target, UserPackageDepSpecOptions())),
+ env.default_destinations()), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_79;
+
+ /**
* \test Test DepList transactional add behaviour.
*
*/
diff --git a/paludis/dep_spec.cc b/paludis/dep_spec.cc
index efc8bcb..bc370ca 100644
--- a/paludis/dep_spec.cc
+++ b/paludis/dep_spec.cc
@@ -759,15 +759,35 @@ namespace
s << "[-" << r.flag() << "]";
}
- void visit(const EqualUseRequirement & r)
+ void visit(const IfMineThenUseRequirement & r)
{
s << "[" << r.flag() << "?]";
}
- void visit(const NotEqualUseRequirement & r)
+ void visit(const IfNotMineThenUseRequirement & r)
{
s << "[" << r.flag() << "!?]";
}
+
+ void visit(const IfMineThenNotUseRequirement & r)
+ {
+ s << "[-" << r.flag() << "?]";
+ }
+
+ void visit(const IfNotMineThenNotUseRequirement & r)
+ {
+ s << "[-" << r.flag() << "!?]";
+ }
+
+ void visit(const EqualUseRequirement & r)
+ {
+ s << "[" << r.flag() << "=]";
+ }
+
+ void visit(const NotEqualUseRequirement & r)
+ {
+ s << "[" << r.flag() << "!=]";
+ }
};
struct PartiallyMadePackageDepSpecData :
diff --git a/paludis/dep_spec_TEST.cc b/paludis/dep_spec_TEST.cc
index 7a50d8d..ffbb06d 100644
--- a/paludis/dep_spec_TEST.cc
+++ b/paludis/dep_spec_TEST.cc
@@ -25,6 +25,7 @@
#include <paludis/util/options.hh>
#include <paludis/util/visitor_cast.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/make_shared_ptr.hh>
#include <paludis/version_requirements.hh>
#include <paludis/use_requirements.hh>
#include <test/test_framework.hh>
@@ -172,6 +173,15 @@ namespace test_cases
TEST_CHECK_STRINGIFY_EQUAL(next(next(m.version_requirements_ptr()->begin()))->version_spec, "1.4");
TEST_CHECK_EQUAL(next(next(m.version_requirements_ptr()->begin()))->version_operator, vo_tilde);
TEST_CHECK(! m.slot_ptr());
+
+ PackageDepSpec n(make_package_dep_spec()
+ .use_requirement(make_shared_ptr(new IfMineThenUseRequirement(UseFlagName("if-mine-then"), tr1::shared_ptr<const PackageID>())))
+ .use_requirement(make_shared_ptr(new IfNotMineThenUseRequirement(UseFlagName("if-not-mine-then"), tr1::shared_ptr<const PackageID>())))
+ .use_requirement(make_shared_ptr(new IfMineThenNotUseRequirement(UseFlagName("if-mine-then-not"), tr1::shared_ptr<const PackageID>())))
+ .use_requirement(make_shared_ptr(new IfNotMineThenNotUseRequirement(UseFlagName("if-not-mine-then-not"), tr1::shared_ptr<const PackageID>())))
+ .use_requirement(make_shared_ptr(new EqualUseRequirement(UseFlagName("equal"), tr1::shared_ptr<const PackageID>())))
+ .use_requirement(make_shared_ptr(new NotEqualUseRequirement(UseFlagName("not-equal"), tr1::shared_ptr<const PackageID>()))));
+ TEST_CHECK_STRINGIFY_EQUAL(n, "*/*[if-mine-then?][if-not-mine-then!?][-if-mine-then-not?][-if-not-mine-then-not!?][equal=][not-equal!=]");
}
} test_package_dep_spec;
diff --git a/paludis/environments/test/test_environment.cc b/paludis/environments/test/test_environment.cc
index bca0957..18e4fab 100644
--- a/paludis/environments/test/test_environment.cc
+++ b/paludis/environments/test/test_environment.cc
@@ -57,8 +57,11 @@ TestEnvironment::~TestEnvironment()
}
bool
-TestEnvironment::query_use(const UseFlagName & u, const PackageID &) const
+TestEnvironment::query_use(const UseFlagName & u, const PackageID & p) const
{
+ if (UseFlagName("pkgname") == u)
+ return PackageNamePart("enabled") == p.name().package;
+
return (std::string::npos != u.data().find("enabled"));
}
diff --git a/paludis/match_package.cc b/paludis/match_package.cc
index 065ab8e..b1e65d7 100644
--- a/paludis/match_package.cc
+++ b/paludis/match_package.cc
@@ -31,44 +31,6 @@
using namespace paludis;
-namespace
-{
- struct UseRequirementChecker :
- ConstVisitor<UseRequirementVisitorTypes>
- {
- bool ok;
- const Environment * const env;
- const PackageID & id;
-
- UseRequirementChecker(const Environment * const e, const PackageID & i) :
- ok(true),
- env(e),
- id(i)
- {
- }
-
- void visit(const EnabledUseRequirement & r)
- {
- ok = env->query_use(r.flag(), id);
- }
-
- void visit(const DisabledUseRequirement & r)
- {
- ok = ! env->query_use(r.flag(), id);
- }
-
- void visit(const EqualUseRequirement & r)
- {
- ok = (env->query_use(r.flag(), id) == env->query_use(r.flag(), *r.package_id()));
- }
-
- void visit(const NotEqualUseRequirement & r)
- {
- ok = ! (env->query_use(r.flag(), id) == env->query_use(r.flag(), *r.package_id()));
- }
- };
-}
-
bool
paludis::match_package(
const Environment & env,
@@ -126,13 +88,8 @@ paludis::match_package(
{
for (UseRequirements::ConstIterator u(spec.use_requirements_ptr()->begin()),
u_end(spec.use_requirements_ptr()->end()) ; u != u_end ; ++u)
- {
- UseRequirementChecker v(&env, entry);
- (*u)->accept(v);
-
- if (! v.ok)
+ if (! (*u)->satisfied_by(&env, entry))
return false;
- }
}
return true;
diff --git a/paludis/repositories/e/package_dep_spec.cc b/paludis/repositories/e/package_dep_spec.cc
index 191a402..8204362 100644
--- a/paludis/repositories/e/package_dep_spec.cc
+++ b/paludis/repositories/e/package_dep_spec.cc
@@ -135,12 +135,23 @@ paludis::erepository::parse_e_package_dep_spec(const std::string & ss, const EAP
default:
{
tr1::shared_ptr<const UseRequirement> req;
- if ('-' == flag.at(0))
+ if ('=' == flag.at(flag.length() - 1))
{
- flag.erase(0, 1);
+ if (! id)
+ throw PackageDepSpecError("Cannot use [use=] without an associated ID");
+
+ flag.erase(flag.length() - 1);
if (flag.empty())
throw PackageDepSpecError("Invalid [] contents");
- req.reset(new DisabledUseRequirement(UseFlagName(flag)));
+ if ('!' == flag.at(flag.length() - 1))
+ {
+ flag.erase(flag.length() - 1);
+ if (flag.empty())
+ throw PackageDepSpecError("Invalid [] contents");
+ req.reset(new NotEqualUseRequirement(UseFlagName(flag), id));
+ }
+ else
+ req.reset(new EqualUseRequirement(UseFlagName(flag), id));
}
else if ('?' == flag.at(flag.length() - 1))
{
@@ -155,10 +166,37 @@ paludis::erepository::parse_e_package_dep_spec(const std::string & ss, const EAP
flag.erase(flag.length() - 1);
if (flag.empty())
throw PackageDepSpecError("Invalid [] contents");
- req.reset(new NotEqualUseRequirement(UseFlagName(flag), id));
+ if ('-' == flag.at(0))
+ {
+ flag.erase(0, 1);
+ if (flag.empty())
+ throw PackageDepSpecError("Invalid [] contents");
+
+ req.reset(new IfNotMineThenNotUseRequirement(UseFlagName(flag), id));
+ }
+ else
+ req.reset(new IfNotMineThenUseRequirement(UseFlagName(flag), id));
}
else
- req.reset(new EqualUseRequirement(UseFlagName(flag), id));
+ {
+ if ('-' == flag.at(0))
+ {
+ flag.erase(0, 1);
+ if (flag.empty())
+ throw PackageDepSpecError("Invalid [] contents");
+
+ req.reset(new IfMineThenNotUseRequirement(UseFlagName(flag), id));
+ }
+ else
+ req.reset(new IfMineThenUseRequirement(UseFlagName(flag), id));
+ }
+ }
+ else if ('-' == flag.at(0))
+ {
+ flag.erase(0, 1);
+ if (flag.empty())
+ throw PackageDepSpecError("Invalid [] contents");
+ req.reset(new DisabledUseRequirement(UseFlagName(flag)));
}
else
req.reset(new EnabledUseRequirement(UseFlagName(flag)));
diff --git a/paludis/repositories/fake/fake_package_id.cc b/paludis/repositories/fake/fake_package_id.cc
index 82781c2..200bff4 100644
--- a/paludis/repositories/fake/fake_package_id.cc
+++ b/paludis/repositories/fake/fake_package_id.cc
@@ -364,11 +364,12 @@ namespace paludis
const QualifiedPackageName name;
const VersionSpec version;
SlotName slot;
+ std::string eapi;
- tr1::shared_ptr<DependencyLabelSequence> build_dependencies_labels;
- tr1::shared_ptr<DependencyLabelSequence> run_dependencies_labels;
- tr1::shared_ptr<DependencyLabelSequence> post_dependencies_labels;
- tr1::shared_ptr<DependencyLabelSequence> suggested_dependencies_labels;
+ mutable tr1::shared_ptr<DependencyLabelSequence> build_dependencies_labels;
+ mutable tr1::shared_ptr<DependencyLabelSequence> run_dependencies_labels;
+ mutable tr1::shared_ptr<DependencyLabelSequence> post_dependencies_labels;
+ mutable tr1::shared_ptr<DependencyLabelSequence> suggested_dependencies_labels;
tr1::shared_ptr<LiteralMetadataPackageIDKey> package_id;
tr1::shared_ptr<LiteralMetadataPackageIDKey> virtual_for;
@@ -388,12 +389,13 @@ namespace paludis
Implementation(const Environment * const e, const tr1::shared_ptr<const FakeRepositoryBase> & r,
const QualifiedPackageName & q, const VersionSpec & v, const PackageID * const id,
- const std::string & eapi) :
+ const std::string & my_eapi) :
env(e),
repository(r),
name(q),
version(v),
slot("0"),
+ eapi(my_eapi),
build_dependencies_labels(new DependencyLabelSequence),
run_dependencies_labels(new DependencyLabelSequence),
post_dependencies_labels(new DependencyLabelSequence),
@@ -406,22 +408,6 @@ namespace paludis
provide(new FakeMetadataSpecTreeKey<ProvideSpecTree>("PROVIDE", "Provided packages",
"", tr1::bind(&erepository::parse_provide, _1,
*erepository::EAPIData::get_instance()->eapi_from_string(eapi)), mkt_normal)),
- build_dependencies(new FakeMetadataSpecTreeKey<DependencySpecTree>("DEPEND", "Build dependencies",
- "", tr1::bind(&erepository::parse_depend, _1,
- *erepository::EAPIData::get_instance()->eapi_from_string(eapi), tr1::shared_ptr<const PackageID>()),
- build_dependencies_labels, mkt_dependencies)),
- run_dependencies(new FakeMetadataSpecTreeKey<DependencySpecTree>("RDEPEND", "Run dependencies",
- "", tr1::bind(&erepository::parse_depend, _1,
- *erepository::EAPIData::get_instance()->eapi_from_string(eapi), tr1::shared_ptr<const PackageID>()),
- run_dependencies_labels, mkt_dependencies)),
- post_dependencies(new FakeMetadataSpecTreeKey<DependencySpecTree>("PDEPEND", "Post dependencies",
- "", tr1::bind(&erepository::parse_depend, _1,
- *erepository::EAPIData::get_instance()->eapi_from_string(eapi), tr1::shared_ptr<const PackageID>()),
- post_dependencies_labels, mkt_dependencies)),
- suggested_dependencies(new FakeMetadataSpecTreeKey<DependencySpecTree>("SDEPEND", "Suggested dependencies",
- "", tr1::bind(&erepository::parse_depend, _1,
- *erepository::EAPIData::get_instance()->eapi_from_string(eapi), tr1::shared_ptr<const PackageID>()),
- suggested_dependencies_labels, mkt_dependencies)),
src_uri(new FakeMetadataSpecTreeKey<FetchableURISpecTree>("SRC_URI", "Source URIs",
"", tr1::bind(&erepository::parse_fetchable_uri, _1,
*erepository::EAPIData::get_instance()->eapi_from_string(eapi)), mkt_dependencies)),
@@ -445,10 +431,6 @@ FakePackageID::FakePackageID(const Environment * const e, const tr1::shared_ptr<
add_metadata_key(_imp->iuse);
add_metadata_key(_imp->license);
add_metadata_key(_imp->provide);
- add_metadata_key(_imp->build_dependencies);
- add_metadata_key(_imp->run_dependencies);
- add_metadata_key(_imp->post_dependencies);
- add_metadata_key(_imp->suggested_dependencies);
}
FakePackageID::~FakePackageID()
@@ -533,24 +515,28 @@ FakePackageID::provide_key() const
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::build_dependencies_key() const
{
+ need_keys_added();
return _imp->build_dependencies;
}
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::run_dependencies_key() const
{
+ need_keys_added();
return _imp->run_dependencies;
}
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::post_dependencies_key() const
{
+ need_keys_added();
return _imp->post_dependencies;
}
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::suggested_dependencies_key() const
{
+ need_keys_added();
return _imp->suggested_dependencies;
}
@@ -575,24 +561,28 @@ FakePackageID::provide_key()
const tr1::shared_ptr<FakeMetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::build_dependencies_key()
{
+ need_keys_added();
return _imp->build_dependencies;
}
const tr1::shared_ptr<FakeMetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::run_dependencies_key()
{
+ need_keys_added();
return _imp->run_dependencies;
}
const tr1::shared_ptr<FakeMetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::post_dependencies_key()
{
+ need_keys_added();
return _imp->post_dependencies;
}
const tr1::shared_ptr<FakeMetadataSpecTreeKey<DependencySpecTree> >
FakePackageID::suggested_dependencies_key()
{
+ need_keys_added();
return _imp->suggested_dependencies;
}
@@ -665,6 +655,37 @@ FakePackageID::arbitrary_less_than_comparison(const PackageID & other) const
void
FakePackageID::need_keys_added() const
{
+ Lock l(_imp->mutex);
+
+ if (! _imp->build_dependencies)
+ {
+ using namespace tr1::placeholders;
+
+ _imp->build_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("DEPEND", "Build dependencies",
+ "", tr1::bind(&erepository::parse_depend, _1,
+ *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi), shared_from_this()),
+ _imp->build_dependencies_labels, mkt_dependencies));
+
+ _imp->run_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("RDEPEND", "Run dependencies",
+ "", tr1::bind(&erepository::parse_depend, _1,
+ *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi), shared_from_this()),
+ _imp->run_dependencies_labels, mkt_dependencies)),
+
+ _imp->post_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("PDEPEND", "Post dependencies",
+ "", tr1::bind(&erepository::parse_depend, _1,
+ *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi), shared_from_this()),
+ _imp->post_dependencies_labels, mkt_dependencies)),
+
+ _imp->suggested_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("SDEPEND", "Suggested dependencies",
+ "", tr1::bind(&erepository::parse_depend, _1,
+ *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi), shared_from_this()),
+ _imp->suggested_dependencies_labels, mkt_dependencies)),
+
+ add_metadata_key(_imp->build_dependencies);
+ add_metadata_key(_imp->run_dependencies);
+ add_metadata_key(_imp->post_dependencies);
+ add_metadata_key(_imp->suggested_dependencies);
+ }
}
std::size_t
diff --git a/paludis/repositories/fake/fake_package_id.hh b/paludis/repositories/fake/fake_package_id.hh
index ccee19a..119c18a 100644
--- a/paludis/repositories/fake/fake_package_id.hh
+++ b/paludis/repositories/fake/fake_package_id.hh
@@ -179,7 +179,8 @@ namespace paludis
class PALUDIS_VISIBLE FakePackageID :
public PackageID,
- private PrivateImplementationPattern<FakePackageID>
+ private PrivateImplementationPattern<FakePackageID>,
+ public tr1::enable_shared_from_this<FakePackageID>
{
private:
PrivateImplementationPattern<FakePackageID>::ImpPtr & _imp;
diff --git a/paludis/use_requirements-fwd.hh b/paludis/use_requirements-fwd.hh
index 4c4d598..23a2aad 100644
--- a/paludis/use_requirements-fwd.hh
+++ b/paludis/use_requirements-fwd.hh
@@ -28,6 +28,10 @@ namespace paludis
class UseRequirementVisitorTypes;
class EnabledUseRequirement;
class DisabledUseRequirement;
+ class IfMineThenUseRequirement;
+ class IfNotMineThenUseRequirement;
+ class IfMineThenNotUseRequirement;
+ class IfNotMineThenNotUseRequirement;
class EqualUseRequirement;
class NotEqualUseRequirement;
}
diff --git a/paludis/use_requirements.cc b/paludis/use_requirements.cc
index 891e98c..fe36355 100644
--- a/paludis/use_requirements.cc
+++ b/paludis/use_requirements.cc
@@ -18,6 +18,7 @@
*/
#include <paludis/use_requirements.hh>
+#include <paludis/environment.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/tr1_memory.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
@@ -97,12 +98,17 @@ UseRequirements::empty() const
return _imp->reqs.empty();
}
+UseRequirement::UseRequirement(const UseFlagName & n) :
+ _name(n)
+{
+}
+
UseRequirement::~UseRequirement()
{
}
EnabledUseRequirement::EnabledUseRequirement(const UseFlagName & n) :
- _name(n)
+ UseRequirement(n)
{
}
@@ -110,14 +116,14 @@ EnabledUseRequirement::~EnabledUseRequirement()
{
}
-const UseFlagName
-EnabledUseRequirement::flag() const
+bool
+EnabledUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
{
- return _name;
+ return env->query_use(flag(), pkg);
}
DisabledUseRequirement::DisabledUseRequirement(const UseFlagName & n) :
- _name(n)
+ UseRequirement(n)
{
}
@@ -125,53 +131,109 @@ DisabledUseRequirement::~DisabledUseRequirement()
{
}
-const UseFlagName
-DisabledUseRequirement::flag() const
+bool
+DisabledUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
{
- return _name;
+ return ! env->query_use(flag(), pkg);
}
-EqualUseRequirement::EqualUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
- _name(n),
+ConditionalUseRequirement::ConditionalUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+ UseRequirement(n),
_id(i)
{
}
-EqualUseRequirement::~EqualUseRequirement()
+ConditionalUseRequirement::~ConditionalUseRequirement()
{
}
-const UseFlagName
-EqualUseRequirement::flag() const
+IfMineThenUseRequirement::IfMineThenUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(n, i)
{
- return _name;
}
-const tr1::shared_ptr<const PackageID>
-EqualUseRequirement::package_id() const
+IfMineThenUseRequirement::~IfMineThenUseRequirement()
{
- return _id;
}
-NotEqualUseRequirement::NotEqualUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
- _name(n),
- _id(i)
+bool
+IfMineThenUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
{
+ return ! env->query_use(flag(), *package_id()) || env->query_use(flag(), pkg);
}
-NotEqualUseRequirement::~NotEqualUseRequirement()
+IfNotMineThenUseRequirement::IfNotMineThenUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(n, i)
+{
+}
+
+IfNotMineThenUseRequirement::~IfNotMineThenUseRequirement()
+{
+}
+
+bool
+IfNotMineThenUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
{
+ return env->query_use(flag(), *package_id()) || env->query_use(flag(), pkg);
}
-const UseFlagName
-NotEqualUseRequirement::flag() const
+IfMineThenNotUseRequirement::IfMineThenNotUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(n, i)
{
- return _name;
}
-const tr1::shared_ptr<const PackageID>
-NotEqualUseRequirement::package_id() const
+IfMineThenNotUseRequirement::~IfMineThenNotUseRequirement()
+{
+}
+
+bool
+IfMineThenNotUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
+{
+ return ! env->query_use(flag(), *package_id()) || ! env->query_use(flag(), pkg);
+}
+
+IfNotMineThenNotUseRequirement::IfNotMineThenNotUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(n, i)
+{
+}
+
+IfNotMineThenNotUseRequirement::~IfNotMineThenNotUseRequirement()
+{
+}
+
+bool
+IfNotMineThenNotUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
+{
+ return env->query_use(flag(), *package_id()) || ! env->query_use(flag(), pkg);
+}
+
+EqualUseRequirement::EqualUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(n, i)
+{
+}
+
+EqualUseRequirement::~EqualUseRequirement()
+{
+}
+
+bool
+EqualUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
+{
+ return env->query_use(flag(), pkg) == env->query_use(flag(), *package_id());
+}
+
+NotEqualUseRequirement::NotEqualUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(n, i)
+{
+}
+
+NotEqualUseRequirement::~NotEqualUseRequirement()
+{
+}
+
+bool
+NotEqualUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
{
- return _id;
+ return env->query_use(flag(), pkg) != env->query_use(flag(), *package_id());
}
diff --git a/paludis/use_requirements.hh b/paludis/use_requirements.hh
index f0f0da3..73065ae 100644
--- a/paludis/use_requirements.hh
+++ b/paludis/use_requirements.hh
@@ -21,6 +21,7 @@
#define PALUDIS_GUARD_PALUDIS_USE_REQUIREMENTS_HH 1
#include <paludis/use_requirements-fwd.hh>
+#include <paludis/environment-fwd.hh>
#include <paludis/package_id-fwd.hh>
#include <paludis/name.hh>
#include <paludis/util/private_implementation_pattern.hh>
@@ -83,6 +84,10 @@ namespace paludis
UseRequirement,
EnabledUseRequirement,
DisabledUseRequirement,
+ IfMineThenUseRequirement,
+ IfNotMineThenUseRequirement,
+ IfMineThenNotUseRequirement,
+ IfNotMineThenNotUseRequirement,
EqualUseRequirement,
NotEqualUseRequirement
>
@@ -98,11 +103,26 @@ namespace paludis
class PALUDIS_VISIBLE UseRequirement :
public virtual ConstAcceptInterface<UseRequirementVisitorTypes>
{
+ private:
+ const UseFlagName _name;
+
public:
+ ///\name Basic operations
+ ///\{
+
+ UseRequirement(const UseFlagName &);
virtual ~UseRequirement() = 0;
+ ///\}
+
/// Our use flag.
- virtual const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
+ const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _name;
+ }
+
+ /// Does the package meet the requirement?
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
};
/**
@@ -115,9 +135,6 @@ namespace paludis
public UseRequirement,
public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, EnabledUseRequirement>
{
- private:
- const UseFlagName _name;
-
public:
///\name Basic operations
///\{
@@ -127,7 +144,7 @@ namespace paludis
///\}
- virtual const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
@@ -140,9 +157,6 @@ namespace paludis
public UseRequirement,
public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, DisabledUseRequirement>
{
- private:
- const UseFlagName _name;
-
public:
///\name Basic operations
///\{
@@ -152,36 +166,151 @@ namespace paludis
///\}
- const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
- * An equal requirement for a use flag.
+ * A use requirement that depends on the use flags of the package
+ * it appears in.
*
* \since 0.26
* \ingroup g_dep_spec
*/
- class PALUDIS_VISIBLE EqualUseRequirement :
- public UseRequirement,
- public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, EqualUseRequirement>
+ class PALUDIS_VISIBLE ConditionalUseRequirement :
+ public UseRequirement
{
private:
- const UseFlagName _name;
const tr1::shared_ptr<const PackageID> _id;
public:
///\name Basic operations
///\{
+ ConditionalUseRequirement(const UseFlagName &, const tr1::shared_ptr<const PackageID> &);
+ ~ConditionalUseRequirement();
+
+ ///\}
+
+ /// Our package.
+ const tr1::shared_ptr<const PackageID> package_id() const PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _id;
+ }
+ };
+
+ /**
+ * An if-then requirement for a use flag.
+ *
+ * \since 0.26
+ * \ingroup g_dep_spec
+ */
+ class PALUDIS_VISIBLE IfMineThenUseRequirement :
+ public ConditionalUseRequirement,
+ public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, IfMineThenUseRequirement>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ IfMineThenUseRequirement(const UseFlagName &, const tr1::shared_ptr<const PackageID> &);
+ ~IfMineThenUseRequirement();
+
+ ///\}
+
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ };
+
+ /**
+ * An if-not-then requirement for a use flag.
+ *
+ * \since 0.26
+ * \ingroup g_dep_spec
+ */
+ class PALUDIS_VISIBLE IfNotMineThenUseRequirement :
+ public ConditionalUseRequirement,
+ public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, IfNotMineThenUseRequirement>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ IfNotMineThenUseRequirement(const UseFlagName &, const tr1::shared_ptr<const PackageID> &);
+ ~IfNotMineThenUseRequirement();
+
+ ///\}
+
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ };
+
+ /**
+ * An if-then-not requirement for a use flag.
+ *
+ * \since 0.26
+ * \ingroup g_dep_spec
+ */
+ class PALUDIS_VISIBLE IfMineThenNotUseRequirement :
+ public ConditionalUseRequirement,
+ public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, IfMineThenNotUseRequirement>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ IfMineThenNotUseRequirement(const UseFlagName &, const tr1::shared_ptr<const PackageID> &);
+ ~IfMineThenNotUseRequirement();
+
+ ///\}
+
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ };
+
+ /**
+ * An if-not-then-not requirement for a use flag.
+ *
+ * \since 0.26
+ * \ingroup g_dep_spec
+ */
+ class PALUDIS_VISIBLE IfNotMineThenNotUseRequirement :
+ public ConditionalUseRequirement,
+ public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, IfNotMineThenNotUseRequirement>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ IfNotMineThenNotUseRequirement(const UseFlagName &, const tr1::shared_ptr<const PackageID> &);
+ ~IfNotMineThenNotUseRequirement();
+
+ ///\}
+
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ };
+
+ /**
+ * An equal requirement for a use flag.
+ *
+ * \since 0.26
+ * \ingroup g_dep_spec
+ */
+ class PALUDIS_VISIBLE EqualUseRequirement :
+ public ConditionalUseRequirement,
+ public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, EqualUseRequirement>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
EqualUseRequirement(const UseFlagName &, const tr1::shared_ptr<const PackageID> &);
~EqualUseRequirement();
///\}
- const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- /// Our package.
- const tr1::shared_ptr<const PackageID> package_id() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
@@ -191,13 +320,9 @@ namespace paludis
* \ingroup g_dep_spec
*/
class PALUDIS_VISIBLE NotEqualUseRequirement :
- public UseRequirement,
+ public ConditionalUseRequirement,
public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, NotEqualUseRequirement>
{
- private:
- const UseFlagName _name;
- const tr1::shared_ptr<const PackageID> _id;
-
public:
///\name Basic operations
///\{
@@ -207,10 +332,7 @@ namespace paludis
///\}
- const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- /// Our package.
- const tr1::shared_ptr<const PackageID> package_id() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual bool satisfied_by(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/python/use_requirements.cc b/python/use_requirements.cc
index 05fef3d..4599cb5 100644
--- a/python/use_requirements.cc
+++ b/python/use_requirements.cc
@@ -20,6 +20,8 @@
#include <python/paludis_python.hh>
#include <paludis/use_requirements.hh>
+#include <paludis/environment.hh>
+#include <paludis/package_id.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/util/visitor-impl.hh>
@@ -86,6 +88,11 @@ void expose_use_requirements()
"flag() -> UseFlagName\n"
"Our use flag."
)
+
+ .def("satisfied_by", &UseRequirement::satisfied_by,
+ "satisfied_by(Environment, PackageID) -> bool\n"
+ "Does the package meet the requirement?"
+ )
;
/**
@@ -109,9 +116,77 @@ void expose_use_requirements()
);
/**
+ * ConditionalUseRequirement
+ */
+ bp::class_<ConditionalUseRequirement, bp::bases<UseRequirement>, boost::noncopyable>
+ (
+ "ConditionalUseRequirement",
+ "A use requirement that depends on the use flags of the package it appears in.",
+ bp::no_init
+ )
+
+ .def("package_id", &ConditionalUseRequirement::package_id,
+ "package_id() -> PackageID\n"
+ "Out package."
+ )
+ ;
+
+ /**
+ * IfMineThenUseRequirement
+ */
+ bp::class_<IfMineThenUseRequirement, bp::bases<ConditionalUseRequirement> >
+ (
+ "IfMineThenUseRequirement",
+ "An if-then requirement for a use flag.",
+ bp::init<const UseFlagName &, const tr1::shared_ptr<const PackageID> &>(
+ "__init__(UseFlagName, PackageID)"
+ )
+ )
+ ;
+
+ /**
+ * IfNotMineThenUseRequirement
+ */
+ bp::class_<IfNotMineThenUseRequirement, bp::bases<ConditionalUseRequirement> >
+ (
+ "IfNotMineThenUseRequirement",
+ "An if-not-then requirement for a use flag.",
+ bp::init<const UseFlagName &, const tr1::shared_ptr<const PackageID> &>(
+ "__init__(UseFlagName, PackageID)"
+ )
+ )
+ ;
+
+ /**
+ * IfMineThenNotUseRequirement
+ */
+ bp::class_<IfMineThenNotUseRequirement, bp::bases<ConditionalUseRequirement> >
+ (
+ "IfMineThenNotUseRequirement",
+ "An if-then-not requirement for a use flag.",
+ bp::init<const UseFlagName &, const tr1::shared_ptr<const PackageID> &>(
+ "__init__(UseFlagName, PackageID)"
+ )
+ )
+ ;
+
+ /**
+ * IfNotMineThenNotUseRequirement
+ */
+ bp::class_<IfNotMineThenNotUseRequirement, bp::bases<ConditionalUseRequirement> >
+ (
+ "IfNotMineThenNotUseRequirement",
+ "An if-not-then-not requirement for a use flag.",
+ bp::init<const UseFlagName &, const tr1::shared_ptr<const PackageID> &>(
+ "__init__(UseFlagName, PackageID)"
+ )
+ )
+ ;
+
+ /**
* EqualUseRequirement
*/
- bp::class_<EqualUseRequirement, bp::bases<UseRequirement> >
+ bp::class_<EqualUseRequirement, bp::bases<ConditionalUseRequirement> >
(
"EqualUseRequirement",
"An equal requirement for a use flag.",
@@ -119,17 +194,12 @@ void expose_use_requirements()
"__init__(UseFlagName, PackageID)"
)
)
-
- .def("package_id", &EqualUseRequirement::package_id,
- "package_id() -> PackageID\n"
- "Our package."
- )
;
/**
* NotEqualUseRequirement
*/
- bp::class_<NotEqualUseRequirement, bp::bases<UseRequirement> >
+ bp::class_<NotEqualUseRequirement, bp::bases<ConditionalUseRequirement> >
(
"NotEqualUseRequirement",
"A not equal requirement for a use flag.",
@@ -137,11 +207,6 @@ void expose_use_requirements()
"__init__(UseFlagName, PackageID)"
)
)
-
- .def("package_id", &NotEqualUseRequirement::package_id,
- "package_id() -> PackageID\n"
- "Our package."
- )
;
}
diff --git a/python/use_requirements_TEST.py b/python/use_requirements_TEST.py
index 563e1ab..82c6ad8 100755
--- a/python/use_requirements_TEST.py
+++ b/python/use_requirements_TEST.py
@@ -27,17 +27,22 @@ class TestCase_1_UseRequirements(unittest.TestCase):
self.r = FakeRepository(self.e, "fake")
self.pid = self.r.add_version("cat/pkg", "1")
- self.ur1 = EnabledUseRequirement("foo")
- self.ur2 = DisabledUseRequirement("foo")
- self.ur3 = EqualUseRequirement("foo", self.pid)
- self.ur4 = NotEqualUseRequirement("foo", self.pid)
+ self.ur1 = EnabledUseRequirement("enabled")
+ self.ur2 = DisabledUseRequirement("enabled")
+ self.ur3 = IfMineThenUseRequirement("foo", self.pid)
+ self.ur4 = IfNotMineThenUseRequirement("foo", self.pid)
+ self.ur5 = IfMineThenNotUseRequirement("foo", self.pid)
+ self.ur6 = IfNotMineThenNotUseRequirement("foo", self.pid)
+ self.ur7 = EqualUseRequirement("foo", self.pid)
+ self.ur8 = NotEqualUseRequirement("foo", self.pid)
def test_01_create(self):
self.assertRaises(Exception, UseRequirement)
+ self.assertRaises(Exception, ConditionalUseRequirement)
def test_02_flag(self):
- self.assertEquals(self.ur1.flag(), UseFlagName("foo"))
- self.assertEquals(self.ur2.flag(), UseFlagName("foo"))
+ self.assertEquals(self.ur1.flag(), UseFlagName("enabled"))
+ self.assertEquals(self.ur2.flag(), UseFlagName("enabled"))
self.assertEquals(self.ur3.flag(), UseFlagName("foo"))
self.assertEquals(self.ur4.flag(), UseFlagName("foo"))
@@ -45,6 +50,22 @@ class TestCase_1_UseRequirements(unittest.TestCase):
self.assertEquals(self.ur3.package_id(), self.pid)
self.assertEquals(self.ur4.package_id(), self.pid)
+ def test_04_satisfied_by(self):
+ self.assert_(self.ur1.satisfied_by(self.e, self.pid))
+ self.assert_(not self.ur2.satisfied_by(self.e, self.pid))
+
+ def test_05_hierarchy(self):
+ self.assert_(isinstance(self.ur1, UseRequirement))
+ self.assert_(not isinstance(self.ur1, ConditionalUseRequirement))
+ self.assert_(isinstance(self.ur2, UseRequirement))
+ self.assert_(not isinstance(self.ur2, ConditionalUseRequirement))
+ self.assert_(isinstance(self.ur3, UseRequirement))
+ self.assert_(isinstance(self.ur3, ConditionalUseRequirement))
+ self.assert_(isinstance(self.ur4, ConditionalUseRequirement))
+ self.assert_(isinstance(self.ur5, ConditionalUseRequirement))
+ self.assert_(isinstance(self.ur6, ConditionalUseRequirement))
+ self.assert_(isinstance(self.ur7, ConditionalUseRequirement))
+ self.assert_(isinstance(self.ur8, ConditionalUseRequirement))
if __name__ == "__main__":
unittest.main()