aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-06-14 19:58:35 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-06-15 10:42:03 +0100
commit706d8f3b19ec8ceca9ca19b0a9b3837346d539f0 (patch)
tree2cdc9a3e5e2d1a9b236d4ecd4ce5ff818d53fcca
parent0d9e1813f031b6b4449654265f66b92595f73122 (diff)
downloadpaludis-706d8f3b19ec8ceca9ca19b0a9b3837346d539f0.tar.gz
paludis-706d8f3b19ec8ceca9ca19b0a9b3837346d539f0.tar.xz
Make parse_user_package_dep_spec more flexible.
parse_user_package_dep_spec will now disambiguate pkg to cat/pkg automatically. To do this it needs an Environment parameter, and optionally also a Filter. UserPackageDepSpecOptions now includes updso_no_disambiguation to disable this. If UserPackageDepSpecOptions includes updso_throw_if_set, and if given something that is a valid set, parse_user_package_dep_spec will throw GotASetNotAPackageDepSpec.
-rw-r--r--paludis/user_dep_spec-fwd.hh20
-rw-r--r--paludis/user_dep_spec.cc92
-rw-r--r--paludis/user_dep_spec.hh13
-rw-r--r--paludis/user_dep_spec.se6
4 files changed, 89 insertions, 42 deletions
diff --git a/paludis/user_dep_spec-fwd.hh b/paludis/user_dep_spec-fwd.hh
index 8a822ed..af7a7ef 100644
--- a/paludis/user_dep_spec-fwd.hh
+++ b/paludis/user_dep_spec-fwd.hh
@@ -22,8 +22,10 @@
#include <paludis/util/attributes.hh>
#include <paludis/util/options-fwd.hh>
+#include <paludis/util/exception.hh>
#include <paludis/dep_spec-fwd.hh>
#include <paludis/package_id-fwd.hh>
+#include <paludis/environment-fwd.hh>
#include <tr1/memory>
#include <iosfwd>
@@ -41,12 +43,24 @@ namespace paludis
typedef Options<UserPackageDepSpecOption> UserPackageDepSpecOptions;
/**
- * Create a PackageDepSpec from user input.
+ * Thrown by paludis::parse_user_package_dep_spec if options includes
+ * updso_throw_if_set and we're given a set.
*
+ * \since 0.28
* \ingroup g_dep_spec
- * \since 0.26
+ * \ingroup g_exceptions
*/
- PackageDepSpec parse_user_package_dep_spec(const std::string &, const UserPackageDepSpecOptions &) PALUDIS_VISIBLE;
+ class PALUDIS_VISIBLE GotASetNotAPackageDepSpec :
+ public Exception
+ {
+ public:
+ ///\name Basic Operations
+ ///\{
+
+ GotASetNotAPackageDepSpec(const std::string &) throw ();
+
+ ///\}
+ };
struct UserSlotExactRequirement;
}
diff --git a/paludis/user_dep_spec.cc b/paludis/user_dep_spec.cc
index 7fd03bd..adfa93a 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -23,6 +23,8 @@
#include <paludis/version_operator.hh>
#include <paludis/version_spec.hh>
#include <paludis/version_requirements.hh>
+#include <paludis/package_database.hh>
+#include <paludis/filter.hh>
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/options.hh>
#include <paludis/util/log.hh>
@@ -32,14 +34,59 @@ using namespace paludis;
#include <paludis/user_dep_spec-se.cc>
+namespace
+{
+ void parse_package_bit(PartiallyMadePackageDepSpec & result, const std::string & ss, const std::string & t,
+ const Environment * const env, const UserPackageDepSpecOptions & options,
+ const Filter & filter)
+ {
+ if (t.length() >= 3 && (0 == t.compare(0, 2, "*/")))
+ {
+ if (! options[updso_allow_wildcards])
+ throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
+
+ if (0 != t.compare(t.length() - 2, 2, "/*"))
+ result.package_name_part(PackageNamePart(t.substr(2)));
+ }
+ else if (t.length() >= 3 && (0 == t.compare(t.length() - 2, 2, "/*")))
+ {
+ if (! options[updso_allow_wildcards])
+ throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
+
+ result.category_name_part(CategoryNamePart(t.substr(0, t.length() - 2)));
+ }
+ else if (t == "*")
+ throw PackageDepSpecError("Use '*/*' not '*' to match everything in '" + stringify(ss) + "'");
+ else if (std::string::npos != t.find('/'))
+ result.package(QualifiedPackageName(t));
+ else
+ {
+ if (options[updso_no_disambiguation])
+ throw PackageDepSpecError("Need an explicit category specified in '" + stringify(ss) + "'");
+ result.package(env->package_database()->fetch_unique_qualified_package_name(PackageNamePart(t), filter));
+ }
+ }
+}
+
PackageDepSpec
-paludis::parse_user_package_dep_spec(const std::string & ss, const UserPackageDepSpecOptions & options)
+paludis::parse_user_package_dep_spec(const std::string & ss, const Environment * const env,
+ const UserPackageDepSpecOptions & options, const Filter & filter)
{
Context context("When parsing package dep spec '" + ss + "':");
if (ss.empty())
throw PackageDepSpecError("Got empty dep spec");
+ if (options[updso_throw_if_set] && std::string::npos == ss.find_first_of("/:[<>=~"))
+ try
+ {
+ if (env->set(SetName(ss)))
+ throw GotASetNotAPackageDepSpec(ss);
+ }
+ catch (const SetNameError &)
+ {
+ }
+
std::string s(ss);
PartiallyMadePackageDepSpec result;
bool had_bracket_version_requirements(false);
@@ -184,23 +231,7 @@ paludis::parse_user_package_dep_spec(const std::string & ss, const UserPackageDe
}
std::string t(s.substr(p, q - p - 1));
- if (t.length() >= 3 && (0 == t.compare(0, 2, "*/")))
- {
- if (! options[updso_allow_wildcards])
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
-
- if (0 != t.compare(t.length() - 2, 2, "/*"))
- result.package_name_part(PackageNamePart(t.substr(2)));
- }
- else if (t.length() >= 3 && (0 == t.compare(t.length() - 2, 2, "/*")))
- {
- if (! options[updso_allow_wildcards])
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
-
- result.category_name_part(CategoryNamePart(t.substr(0, t.length() - 2)));
- }
- else
- result.package(QualifiedPackageName(t));
+ parse_package_bit(result, ss, t, env, options, filter);
if ('*' == s.at(s.length() - 1))
{
@@ -216,25 +247,7 @@ paludis::parse_user_package_dep_spec(const std::string & ss, const UserPackageDe
result.version_requirement(VersionRequirement(op, VersionSpec(s.substr(q))));
}
else
- {
- if (s.length() >= 3 && (0 == s.compare(0, 2, "*/")))
- {
- if (! options[updso_allow_wildcards])
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
-
- if (0 != s.compare(s.length() - 2, 2, "/*"))
- result.package_name_part(PackageNamePart(s.substr(2)));
- }
- else if (s.length() >= 3 && (0 == s.compare(s.length() - 2, 2, "/*")))
- {
- if (! options[updso_allow_wildcards])
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
-
- result.category_name_part(CategoryNamePart(s.substr(0, s.length() - 2)));
- }
- else
- result.package(QualifiedPackageName(s));
- }
+ parse_package_bit(result, ss, s, env, options, filter);
return result;
}
@@ -255,3 +268,8 @@ UserSlotExactRequirement::as_string() const
return ":" + stringify(_s);
}
+GotASetNotAPackageDepSpec::GotASetNotAPackageDepSpec(const std::string & s) throw () :
+ Exception("'" + s + "' is a set, not a package")
+{
+}
+
diff --git a/paludis/user_dep_spec.hh b/paludis/user_dep_spec.hh
index c5bda68..6af3b85 100644
--- a/paludis/user_dep_spec.hh
+++ b/paludis/user_dep_spec.hh
@@ -23,9 +23,22 @@
#include <paludis/user_dep_spec-fwd.hh>
#include <paludis/dep_spec.hh>
#include <paludis/slot_requirement.hh>
+#include <paludis/filter.hh>
namespace paludis
{
+ /**
+ * Create a PackageDepSpec from user input.
+ *
+ * \ingroup g_dep_spec
+ * \since 0.28
+ */
+ PackageDepSpec parse_user_package_dep_spec(
+ const std::string &,
+ const Environment * const,
+ const UserPackageDepSpecOptions &,
+ const Filter & = filter::All()) PALUDIS_VISIBLE;
+
class PALUDIS_VISIBLE UserSlotExactRequirement :
public SlotExactRequirement
{
diff --git a/paludis/user_dep_spec.se b/paludis/user_dep_spec.se
index 86847b8..965c917 100644
--- a/paludis/user_dep_spec.se
+++ b/paludis/user_dep_spec.se
@@ -5,11 +5,13 @@ make_enum_UserPackageDepSpecOption()
{
prefix updso
- key updso_allow_wildcards "Allow wildcards for category, package"
+ key updso_allow_wildcards "Allow wildcards for category, package"
+ key updso_throw_if_set "Check if it's a set, and throw GotASetNotAPackageDepSpec if so. \since 0.28"
+ key updso_no_disambiguation "Require an explicit category. \since 0.28"
doxygen_comment << "END"
/**
- * Options for parse_user_package_dep_spec
+ * Options for parse_user_package_dep_spec.
*
* \ingroup g_dep_spec
* \since 0.26