aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-04-04 14:25:36 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-04-04 14:25:36 +0100
commit4cd6e7042bb22cc8671f034f9849532d04fad891 (patch)
treed4234252ad89ecb22ceb5a498dd20adc49c5e6cf
parent4cd184dd41cc756de430499a36972a6824b68f90 (diff)
downloadpaludis-4cd6e7042bb22cc8671f034f9849532d04fad891.tar.gz
paludis-4cd6e7042bb22cc8671f034f9849532d04fad891.tar.xz
[.(mask)?] specs
-rw-r--r--paludis/package_dep_spec_constraint.cc119
-rw-r--r--paludis/package_dep_spec_constraint.se1
-rw-r--r--paludis/user_dep_spec.cc6
3 files changed, 116 insertions, 10 deletions
diff --git a/paludis/package_dep_spec_constraint.cc b/paludis/package_dep_spec_constraint.cc
index dcdb7ad..5db0b2b 100644
--- a/paludis/package_dep_spec_constraint.cc
+++ b/paludis/package_dep_spec_constraint.cc
@@ -26,6 +26,7 @@
#include <paludis/dep_spec.hh>
#include <paludis/environment.hh>
#include <paludis/repository.hh>
+#include <paludis/mask.hh>
#include <paludis/util/pool-impl.hh>
#include <paludis/util/pimp-impl.hh>
@@ -808,6 +809,71 @@ namespace
return false;
}
};
+
+ struct AssociatedKeyFinder
+ {
+ const Environment * const env;
+ const std::shared_ptr<const PackageID> id;
+
+ const MetadataKey * const visit(const UserMask &) const
+ {
+ return 0;
+ }
+
+ const MetadataKey * const visit(const UnacceptedMask & m) const
+ {
+ auto k(id->find_metadata(m.unaccepted_key_name()));
+ if (k != id->end_metadata())
+ return &**k;
+ else
+ return 0;
+ }
+
+ const MetadataKey * const visit(const RepositoryMask &) const
+ {
+ return 0;
+ }
+
+ const MetadataKey * const visit(const UnsupportedMask &) const
+ {
+ return 0;
+ }
+
+ const MetadataKey * const visit(const AssociationMask &) const
+ {
+ return 0;
+ }
+ };
+
+ struct MaskChecker
+ {
+ const std::string key;
+
+ bool visit(const UserMask & m) const
+ {
+ return key == "*" || key == "user" || m.token() == key;
+ }
+
+ bool visit(const UnacceptedMask & m) const
+ {
+ return key == "*" || key == "unaccepted" || m.unaccepted_key_name() == key;
+ }
+
+ bool visit(const RepositoryMask & m) const
+ {
+ return key == "*" || key == "repository" || m.token() == key;
+ }
+
+ bool visit(const UnsupportedMask &) const
+ {
+ return key == "*" || key == "unsupported";
+ }
+
+ bool visit(const AssociationMask &) const
+ {
+ return key == "*" || key == "association";
+ }
+ };
}
bool
@@ -816,6 +882,7 @@ KeyConstraint::matches(
const std::shared_ptr<const PackageID> & id) const
{
const MetadataKey * k(0);
+ const Mask * m(0);
switch (key_type())
{
@@ -885,17 +952,29 @@ KeyConstraint::matches(
case kckt_repo:
{
auto repo(env->fetch_repository(id->repository_name()));
- Repository::MetadataConstIterator m(repo->find_metadata(key()));
- if (m != repo->end_metadata())
- k = m->get();
+ Repository::MetadataConstIterator mm(repo->find_metadata(key()));
+ if (mm != repo->end_metadata())
+ k = mm->get();
}
break;
case kckt_id:
{
- PackageID::MetadataConstIterator m(id->find_metadata(key()));
- if (m != id->end_metadata())
- k = m->get();
+ PackageID::MetadataConstIterator mm(id->find_metadata(key()));
+ if (mm != id->end_metadata())
+ k = mm->get();
+ }
+ break;
+
+ case kckt_id_mask:
+ {
+ for (auto mm(id->begin_masks()), mm_end(id->end_masks()) ;
+ mm != mm_end ; ++mm)
+ if ((*mm)->accept_returning<bool>(MaskChecker{key()}))
+ {
+ m = &**mm;
+ break;
+ }
}
break;
@@ -903,15 +982,23 @@ KeyConstraint::matches(
break;
}
- if (! k)
+ if ((! k) && (! m))
return false;
if (operation() == kco_question)
return true;
else
{
- KeyComparator c(env, id, pattern(), operation());
- return k->accept_returning<bool>(c);
+ if (m)
+ k = m->accept_returning<const MetadataKey *>(AssociatedKeyFinder{env, id});
+
+ if (k)
+ {
+ KeyComparator c(env, id, pattern(), operation());
+ return k->accept_returning<bool>(c);
+ }
+
+ return false;
}
}
@@ -925,7 +1012,8 @@ KeyConstraint::as_raw_string() const
{
case kckt_id: break;
case kckt_id_role: s << "$"; break;
- case kckt_repo: s << "::"; break;
+ case kckt_id_mask: s << "("; break;
+ case kckt_repo: s << "::"; break;
case kckt_repo_role: s << "::$"; break;
case last_kckt:
break;
@@ -944,6 +1032,17 @@ KeyConstraint::as_raw_string() const
throw InternalError(PALUDIS_HERE, "Bad KeyConstraintOperation");
}
+ switch (key_type())
+ {
+ case kckt_id: break;
+ case kckt_id_role: break;
+ case kckt_id_mask: s << ")"; break;
+ case kckt_repo: break;
+ case kckt_repo_role: break;
+ case last_kckt:
+ break;
+ }
+
s << "]";
return s.str();
diff --git a/paludis/package_dep_spec_constraint.se b/paludis/package_dep_spec_constraint.se
index 3322a9e..54982f8 100644
--- a/paludis/package_dep_spec_constraint.se
+++ b/paludis/package_dep_spec_constraint.se
@@ -17,6 +17,7 @@ make_enum_KeyConstraintKeyType()
key kckt_id "A regular [.key] constraint"
key kckt_id_role "A role [.\$key] constraint"
+ key kckt_id_mask "A role [.(mask)] constraint"
key kckt_repo "A [.::repo] constraint"
key kckt_repo_role "A [.::\$repo] constraint"
}
diff --git a/paludis/user_dep_spec.cc b/paludis/user_dep_spec.cc
index e4ee764..37f1c12 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -373,6 +373,12 @@ paludis::parse_user_key_constraint(const std::string & s)
type = kckt_id_role;
key.erase(0, 1);
}
+ else if (0 == key.compare(0, 1, "(", 0, 1) && ')' == key.at(key.length() - 1))
+ {
+ type = kckt_id_mask;
+ key.erase(0, 1);
+ key.erase(key.length() - 1);
+ }
return std::make_tuple(type, key, op, value);
}