[paludis-commits] r4117 - in trunk: . doc/api/cplusplus/examples paludis paludis/environments/test paludis/repositories/e paludis/repositories/fake python

dleverton at svn.pioto.org dleverton at svn.pioto.org
Mon Dec 31 14:13:05 UTC 2007


Author: dleverton
Date: 2007-12-31 14:13:04 +0000 (Mon, 31 Dec 2007)
New Revision: 4117

Modified:
   trunk/ChangeLog
   trunk/doc/api/cplusplus/examples/example_dep_spec.cc
   trunk/paludis/dep_list_TEST.cc
   trunk/paludis/dep_spec.cc
   trunk/paludis/dep_spec_TEST.cc
   trunk/paludis/environments/test/test_environment.cc
   trunk/paludis/match_package.cc
   trunk/paludis/repositories/e/package_dep_spec.cc
   trunk/paludis/repositories/fake/fake_package_id.cc
   trunk/paludis/repositories/fake/fake_package_id.hh
   trunk/paludis/use_requirements-fwd.hh
   trunk/paludis/use_requirements.cc
   trunk/paludis/use_requirements.hh
   trunk/python/use_requirements.cc
   trunk/python/use_requirements_TEST.py
Log:
Add some more UseRequirement variants, and change the syntax of the old ones.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/ChangeLog	2007-12-31 14:13:04 UTC (rev 4117)
@@ -5,6 +5,13 @@
 only listed in SVN log. For a summary of what has changed between releases,
 see the NEWS file. This file is occasionally pruned to ChangeLog.old.bz2.
 
+2007-12-31 David Leverton
+
+	* doc/api/cplusplus/examples/, paludis/,
+	paludis/environments/test/, paludis/repositories/e/,
+	paludis/repositories/fake/, python/: Add some more UseRequirement
+	variants, and change the syntax of the old ones.
+
 2007-12-30 Ciaran McCreesh
 
 	* paludis/: Kill PStream in favour of

Modified: trunk/doc/api/cplusplus/examples/example_dep_spec.cc
===================================================================
--- trunk/doc/api/cplusplus/examples/example_dep_spec.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/doc/api/cplusplus/examples/example_dep_spec.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -51,14 +51,34 @@
             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() << "')";
         }
     };
 }

Modified: trunk/paludis/dep_list_TEST.cc
===================================================================
--- trunk/paludis/dep_list_TEST.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/dep_list_TEST.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -1391,6 +1391,394 @@
     } 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.
      *
      */

Modified: trunk/paludis/dep_spec.cc
===================================================================
--- trunk/paludis/dep_spec.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/dep_spec.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -759,15 +759,35 @@
             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 :

Modified: trunk/paludis/dep_spec_TEST.cc
===================================================================
--- trunk/paludis/dep_spec_TEST.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/dep_spec_TEST.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -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 @@
             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;
 

Modified: trunk/paludis/environments/test/test_environment.cc
===================================================================
--- trunk/paludis/environments/test/test_environment.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/environments/test/test_environment.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -57,8 +57,11 @@
 }
 
 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"));
 }
 

Modified: trunk/paludis/match_package.cc
===================================================================
--- trunk/paludis/match_package.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/match_package.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -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 @@
     {
         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;

Modified: trunk/paludis/repositories/e/package_dep_spec.cc
===================================================================
--- trunk/paludis/repositories/e/package_dep_spec.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/repositories/e/package_dep_spec.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -135,12 +135,23 @@
             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,11 +166,38 @@
                             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)));
                     result.use_requirement(req);

Modified: trunk/paludis/repositories/fake/fake_package_id.cc
===================================================================
--- trunk/paludis/repositories/fake/fake_package_id.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/repositories/fake/fake_package_id.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -364,11 +364,12 @@
         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 @@
 
         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 @@
             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 @@
     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 @@
 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 @@
 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 @@
 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

Modified: trunk/paludis/repositories/fake/fake_package_id.hh
===================================================================
--- trunk/paludis/repositories/fake/fake_package_id.hh	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/repositories/fake/fake_package_id.hh	2007-12-31 14:13:04 UTC (rev 4117)
@@ -179,7 +179,8 @@
 
     class PALUDIS_VISIBLE FakePackageID :
         public PackageID,
-        private PrivateImplementationPattern<FakePackageID>
+        private PrivateImplementationPattern<FakePackageID>,
+        public tr1::enable_shared_from_this<FakePackageID>
     {
         private:
             PrivateImplementationPattern<FakePackageID>::ImpPtr & _imp;

Modified: trunk/paludis/use_requirements-fwd.hh
===================================================================
--- trunk/paludis/use_requirements-fwd.hh	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/use_requirements-fwd.hh	2007-12-31 14:13:04 UTC (rev 4117)
@@ -28,6 +28,10 @@
     class UseRequirementVisitorTypes;
     class EnabledUseRequirement;
     class DisabledUseRequirement;
+    class IfMineThenUseRequirement;
+    class IfNotMineThenUseRequirement;
+    class IfMineThenNotUseRequirement;
+    class IfNotMineThenNotUseRequirement;
     class EqualUseRequirement;
     class NotEqualUseRequirement;
 }

Modified: trunk/paludis/use_requirements.cc
===================================================================
--- trunk/paludis/use_requirements.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/use_requirements.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -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 @@
     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 @@
 {
 }
 
-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 @@
 {
 }
 
-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)
 {
 }
 
-const UseFlagName
-NotEqualUseRequirement::flag() const
+IfNotMineThenUseRequirement::~IfNotMineThenUseRequirement()
 {
-    return _name;
 }
 
-const tr1::shared_ptr<const PackageID>
-NotEqualUseRequirement::package_id() const
+bool
+IfNotMineThenUseRequirement::satisfied_by(const Environment * const env, const PackageID & pkg) const
 {
-    return _id;
+    return env->query_use(flag(), *package_id()) || env->query_use(flag(), pkg);
 }
 
+IfMineThenNotUseRequirement::IfMineThenNotUseRequirement(const UseFlagName & n, const tr1::shared_ptr<const PackageID> & i) :
+    ConditionalUseRequirement(n, i)
+{
+}
+
+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 env->query_use(flag(), pkg) != env->query_use(flag(), *package_id());
+}
+

Modified: trunk/paludis/use_requirements.hh
===================================================================
--- trunk/paludis/use_requirements.hh	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/paludis/use_requirements.hh	2007-12-31 14:13:04 UTC (rev 4117)
@@ -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 @@
             UseRequirement,
             EnabledUseRequirement,
             DisabledUseRequirement,
+            IfMineThenUseRequirement,
+            IfNotMineThenUseRequirement,
+            IfMineThenNotUseRequirement,
+            IfNotMineThenNotUseRequirement,
             EqualUseRequirement,
             NotEqualUseRequirement
         >
@@ -98,11 +103,26 @@
     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 @@
         public UseRequirement,
         public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, EnabledUseRequirement>
     {
-        private:
-            const UseFlagName _name;
-
         public:
             ///\name Basic operations
             ///\{
@@ -127,7 +144,7 @@
 
             ///\}
 
-            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 @@
         public UseRequirement,
         public ConstAcceptInterfaceVisitsThis<UseRequirementVisitorTypes, DisabledUseRequirement>
     {
-        private:
-            const UseFlagName _name;
-
         public:
             ///\name Basic operations
             ///\{
@@ -152,36 +166,151 @@
 
             ///\}
 
-            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 @@
      * \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 @@
 
             ///\}
 
-            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));
     };
 }
 

Modified: trunk/python/use_requirements.cc
===================================================================
--- trunk/python/use_requirements.cc	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/python/use_requirements.cc	2007-12-31 14:13:04 UTC (rev 4117)
@@ -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 @@
                 "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 @@
         );
 
     /**
+     * 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 @@
              "__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 @@
              "__init__(UseFlagName, PackageID)"
              )
         )
-
-        .def("package_id", &NotEqualUseRequirement::package_id,
-                "package_id() -> PackageID\n"
-                "Our package."
-            )
         ;
 
 }

Modified: trunk/python/use_requirements_TEST.py
===================================================================
--- trunk/python/use_requirements_TEST.py	2007-12-31 02:02:23 UTC (rev 4116)
+++ trunk/python/use_requirements_TEST.py	2007-12-31 14:13:04 UTC (rev 4117)
@@ -27,17 +27,22 @@
         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 @@
         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()



More information about the paludis-commits mailing list