aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-28 09:38:36 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-28 09:38:36 +0000
commit7f03646f03ede9a5aef199a9073366cf98925197 (patch)
tree4b8826ff1eea0bd6b1a0707c83b81338c3ae88b8
parent081bfb52479b562263b688b07f976baa3e068665 (diff)
downloadpaludis-7f03646f03ede9a5aef199a9073366cf98925197.tar.gz
paludis-7f03646f03ede9a5aef199a9073366cf98925197.tar.xz
Better provide handling
-rw-r--r--paludis/dep_atom_flattener.cc84
-rw-r--r--paludis/dep_atom_flattener.hh74
-rw-r--r--paludis/dep_list.cc56
-rw-r--r--paludis/dep_list.hh21
-rw-r--r--paludis/dep_parser.cc15
-rw-r--r--paludis/dep_parser.hh22
-rw-r--r--paludis/files.m43
-rw-r--r--paludis/version_metadata.cc20
-rw-r--r--paludis/version_metadata.hh4
-rw-r--r--src/command_line.cc5
-rw-r--r--src/command_line.hh3
-rw-r--r--src/install.cc1
12 files changed, 269 insertions, 39 deletions
diff --git a/paludis/dep_atom_flattener.cc b/paludis/dep_atom_flattener.cc
new file mode 100644
index 0000000..1753454
--- /dev/null
+++ b/paludis/dep_atom_flattener.cc
@@ -0,0 +1,84 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "dep_atom_flattener.hh"
+#include "package_dep_atom.hh"
+#include "all_dep_atom.hh"
+#include "any_dep_atom.hh"
+#include "block_dep_atom.hh"
+#include "use_dep_atom.hh"
+
+using namespace paludis;
+
+DepAtomFlattener::DepAtomFlattener(
+ const Environment * const env,
+ const PackageDatabaseEntry * const pkg,
+ DepAtom::ConstPointer a) :
+ _env(env),
+ _pkg(pkg),
+ _a(a),
+ _done(false)
+{
+}
+
+DepAtomFlattener::~DepAtomFlattener()
+{
+}
+
+DepAtomFlattener::Iterator
+DepAtomFlattener::begin()
+{
+ if (! _done)
+ {
+ _a->accept(static_cast<DepAtomVisitorTypes::ConstVisitor *>(this));
+ _done = true;
+ }
+
+ return _atoms.begin();
+}
+
+void DepAtomFlattener::visit(const AllDepAtom * a)
+{
+ std::for_each(a->begin(), a->end(), accept_visitor(
+ static_cast<DepAtomVisitorTypes::ConstVisitor *>(this)));
+}
+
+void DepAtomFlattener::visit(const AnyDepAtom *)
+{
+ throw paludis::InternalError(PALUDIS_HERE, "Not allowed an AnyDepAtom");
+}
+
+void DepAtomFlattener::visit(const UseDepAtom * u)
+{
+ if (_env->query_use(u->flag(), _pkg) ^ u->inverse())
+ std::for_each(u->begin(), u->end(), accept_visitor(
+ static_cast<DepAtomVisitorTypes::ConstVisitor *>(this)));
+}
+
+void DepAtomFlattener::visit(const BlockDepAtom *)
+{
+ throw paludis::InternalError(PALUDIS_HERE, "Not allowed a BlockDepAtom");
+}
+
+void DepAtomFlattener::visit(const PackageDepAtom * p)
+{
+ _atoms.push_back(p);
+}
+
diff --git a/paludis/dep_atom_flattener.hh b/paludis/dep_atom_flattener.hh
new file mode 100644
index 0000000..90836fd
--- /dev/null
+++ b/paludis/dep_atom_flattener.hh
@@ -0,0 +1,74 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_FLATTENER_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_ATOM_FLATTENER_HH 1
+
+#include <paludis/attributes.hh>
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_atom_visitor.hh>
+#include <paludis/environment.hh>
+#include <paludis/instantiation_policy.hh>
+#include <paludis/package_database.hh>
+#include <list>
+
+namespace paludis
+{
+ class DepAtomFlattener :
+ private InstantiationPolicy<DepAtomFlattener, instantiation_method::NonCopyableTag>,
+ protected DepAtomVisitorTypes::ConstVisitor
+ {
+ private:
+ const Environment * const _env;
+
+ const PackageDatabaseEntry * const _pkg;
+
+ DepAtom::ConstPointer _a;
+
+ mutable std::list<const PackageDepAtom *> _atoms;
+
+ mutable bool _done;
+
+ protected:
+ void visit(const AllDepAtom *);
+ void visit(const AnyDepAtom *) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const UseDepAtom *);
+ void visit(const BlockDepAtom *) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const PackageDepAtom *);
+
+ public:
+ DepAtomFlattener(const Environment * const,
+ const PackageDatabaseEntry * const,
+ const DepAtom::ConstPointer);
+
+ ~DepAtomFlattener();
+
+ typedef std::list<const PackageDepAtom *>::const_iterator Iterator;
+
+ Iterator begin();
+
+ Iterator end() const
+ {
+ return _atoms.end();
+ }
+ };
+}
+
+#endif
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index 9ec9c85..14abc1f 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -21,6 +21,7 @@
#include "any_dep_atom.hh"
#include "block_dep_atom.hh"
#include "container_entry.hh"
+#include "dep_atom_flattener.hh"
#include "dep_list.hh"
#include "dep_parser.hh"
#include "filter_insert_iterator.hh"
@@ -107,6 +108,7 @@ namespace paludis
bool recursive_deps;
bool drop_circular;
bool drop_self_circular;
+ bool drop_all;
bool ignore_installed;
///}
@@ -126,6 +128,7 @@ namespace paludis
recursive_deps(true),
drop_circular(false),
drop_self_circular(false),
+ drop_all(false),
ignore_installed(false),
stack_depth(0),
max_stack_depth(100)
@@ -158,10 +161,10 @@ DepList::add(DepAtom::ConstPointer atom)
_implementation->merge_list_insert_pos = _implementation->merge_list.end();
while (i != _implementation->merge_list.end())
{
- if (! i->get<dle_has_predeps>())
+ if (! i->get<dle_has_predeps>() && ! _implementation->drop_all)
throw InternalError(PALUDIS_HERE, "dle_has_predeps not set for " + stringify(*i));
- else if (! i->get<dle_has_trypredeps>())
+ else if (! i->get<dle_has_trypredeps>() && ! _implementation->drop_all)
{
Save<const DepListEntry *> save_current_package(
&_implementation->current_package, &*i);
@@ -172,7 +175,7 @@ DepList::add(DepAtom::ConstPointer atom)
i->set<dle_has_trypredeps>(true);
}
- else if (! i->get<dle_has_postdeps>())
+ else if (! i->get<dle_has_postdeps>() && ! _implementation->drop_all)
{
Save<const DepListEntry *> save_current_package(
&_implementation->current_package, &*i);
@@ -194,7 +197,7 @@ DepList::add(DepAtom::ConstPointer atom)
}
void
-DepList::_add(DepAtom::ConstPointer atom)
+DepList::_add_raw(const DepAtom * const atom)
{
/* keep track of stack depth */
Save<int> old_stack_depth(&_implementation->stack_depth,
@@ -224,10 +227,10 @@ DepList::_add(DepAtom::ConstPointer atom)
}
void
-DepList::_add_in_role(DepAtom::ConstPointer atom, const std::string & role)
+DepList::_add_in_role_raw(const DepAtom * const atom, const std::string & role)
{
Context context("When adding " + role + ":");
- _add(atom);
+ _add_raw(atom);
}
DepList::Iterator
@@ -333,6 +336,36 @@ DepList::visit(const PackageDepAtom * const p)
metadata, match->get<pde_repository>(),
false, false, false)));
+ /* if we provide things, also insert them. */
+ /// \bug PROVIDE can contain use? blocks.
+ if (! metadata->get(vmk_provide).empty())
+ {
+ DepParserOptions dep_parser_options;
+ dep_parser_options.set(dpo_qualified_package_names);
+ DepAtom::ConstPointer provide(DepParser::parse(metadata->get(vmk_provide), dep_parser_options));
+
+ CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e(0);
+
+ if (_implementation->current_package)
+ e = CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag>(
+ new PackageDatabaseEntry(
+ _implementation->current_package->get<dle_name>(),
+ _implementation->current_package->get<dle_version>(),
+ _implementation->current_package->get<dle_repository>()));
+
+ DepAtomFlattener f(_implementation->environment, e.raw_pointer(), provide);
+
+ for (DepAtomFlattener::Iterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
+ {
+ Save<bool> save_check(&_implementation->drop_all, true);
+ Save<std::list<DepListEntry>::iterator> old_p(
+ &_implementation->merge_list_insert_pos, next(merge_entry));
+ _add_in_role_raw(*p, "PROVIDE");
+ next(merge_entry)->set<dle_has_predeps>(true);
+ }
+ }
+
+
Save<std::list<DepListEntry>::iterator> old_merge_list_insert_pos(
&_implementation->merge_list_insert_pos, merge_entry);
@@ -344,14 +377,15 @@ DepList::visit(const PackageDepAtom * const p)
&*merge_entry);
/* merge depends */
- if (! merge_entry->get<dle_has_predeps>())
+ if ((! merge_entry->get<dle_has_predeps>()) && ! (_implementation->drop_all))
{
_add_in_role(DepParser::parse(metadata->get(vmk_depend)), "DEPEND");
merge_entry->set<dle_has_predeps>(true);
}
/* merge rdepends */
- if (! merge_entry->get<dle_has_trypredeps>() && dlro_always != _implementation->rdepend_post)
+ if (! merge_entry->get<dle_has_trypredeps>() && dlro_always != _implementation->rdepend_post
+ && ! _implementation->drop_all)
{
try
{
@@ -554,6 +588,12 @@ DepList::set_drop_self_circular(const bool value)
}
void
+DepList::set_drop_all(const bool value)
+{
+ _implementation->drop_all = value;
+}
+
+void
DepList::set_ignore_installed(const bool value)
{
_implementation->ignore_installed = value;
diff --git a/paludis/dep_list.hh b/paludis/dep_list.hh
index 3f0f968..5cb6cf5 100644
--- a/paludis/dep_list.hh
+++ b/paludis/dep_list.hh
@@ -202,8 +202,19 @@ namespace paludis
protected DepAtomVisitorTypes::ConstVisitor
{
private:
- void _add(DepAtom::ConstPointer);
- void _add_in_role(DepAtom::ConstPointer, const std::string & role);
+ void _add_raw(const DepAtom * const);
+
+ void _add(DepAtom::ConstPointer a)
+ {
+ _add_raw(a.raw_pointer());
+ }
+
+ void _add_in_role_raw(const DepAtom * const, const std::string & role);
+
+ void _add_in_role(DepAtom::ConstPointer a, const std::string & role)
+ {
+ _add_in_role_raw(a.raw_pointer(), role);
+ }
protected:
///\name Visit functions
@@ -265,6 +276,12 @@ namespace paludis
void set_drop_circular(const bool value);
/**
+ * Behaviour: if set, any dependencies are treated as if
+ * they do not exist.
+ */
+ void set_drop_all(const bool value);
+
+ /**
* Behaviour: ignore installed packages.
*/
void set_ignore_installed(const bool value);
diff --git a/paludis/dep_parser.cc b/paludis/dep_parser.cc
index ebe9095..78e1732 100644
--- a/paludis/dep_parser.cc
+++ b/paludis/dep_parser.cc
@@ -53,7 +53,7 @@ enum DepParserState
};
CompositeDepAtom::ConstPointer
-DepParser::parse(const std::string & s)
+DepParser::parse(const std::string & s, const DepParserOptions & opts)
{
Context context("When parsing dependency string '" + s + "':");
@@ -115,6 +115,10 @@ DepParser::parse(const std::string & s)
case dpl_double_bar:
{
+ if (! opts[dpo_allow_any_blocks])
+ throw DepStringParseError(s,
+ "|| () blocks are disallowed here");
+
CompositeDepAtom::Pointer a(new AnyDepAtom);
stack.top()->add_child(a);
stack.push(a);
@@ -273,3 +277,12 @@ DepParser::parse(const std::string & s)
return result;
}
+DepParserOptions
+DepParser::default_options()
+{
+ DepParserOptions result;
+ result.set(dpo_qualified_package_names);
+ result.set(dpo_allow_any_blocks);
+ return result;
+}
+
diff --git a/paludis/dep_parser.hh b/paludis/dep_parser.hh
index a8685c8..b283fcc 100644
--- a/paludis/dep_parser.hh
+++ b/paludis/dep_parser.hh
@@ -25,6 +25,7 @@
#include <paludis/instantiation_policy.hh>
#include <paludis/exception.hh>
#include <paludis/dep_lexer.hh>
+#include <bitset>
#include <string>
/** \file
@@ -67,18 +68,37 @@ namespace paludis
};
/**
+ * Options for a DepParser.
+ */
+ enum DepParserOptionValues
+ {
+ dpo_qualified_package_names, ///< Tokens must be qualified package names
+ dpo_allow_any_blocks, ///< Allow || () blocks?
+ last_dpo
+ };
+
+ /**
+ * A set of options for DepParser.
+ */
+ typedef std::bitset<last_dpo> DepParserOptions;
+
+ /**
* The DepParser converts string representations of a dependency
* specification into a DepAtom instance.
*/
class DepParser :
private InstantiationPolicy<DepParser, instantiation_method::NonInstantiableTag>
{
+ protected:
+ static DepParserOptions default_options();
+
public:
/**
* Parse a given dependency string, and return an appropriate
* DepAtom tree.
*/
- static CompositeDepAtom::ConstPointer parse(const std::string & s);
+ static CompositeDepAtom::ConstPointer parse(const std::string & s,
+ const DepParserOptions & opts = default_options());
};
}
diff --git a/paludis/files.m4 b/paludis/files.m4
index 6e6e4be..4007263 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -27,10 +27,12 @@ add(`default_environment', `hh', `cc')
add(`deleter', `hh', `cc', `test')
add(`dep_atom', `hh', `cc')
add(`dep_atom_dumper', `hh', `cc', `test')
+add(`dep_atom_flattener', `hh', `cc')
add(`dep_atom_visitor', `hh', `cc')
add(`dep_lexer', `hh', `cc', `test')
add(`dep_list', `hh', `cc', `test')
add(`dep_parser', `hh', `cc', `test')
+add(`destringify', `hh', `cc', `test')
add(`dir_iterator', `hh', `cc', `test', `testscript')
add(`environment', `hh', `cc')
add(`exception', `hh', `cc')
@@ -78,4 +80,3 @@ add(`version_operator', `hh', `cc', `test')
add(`version_spec', `hh', `cc', `test')
add(`virtual_constructor', `hh', `cc', `test')
add(`visitor', `hh', `cc', `test')
-add(`destringify', `hh', `cc', `test')
diff --git a/paludis/version_metadata.cc b/paludis/version_metadata.cc
index cc22137..351689e 100644
--- a/paludis/version_metadata.cc
+++ b/paludis/version_metadata.cc
@@ -126,23 +126,3 @@ VersionMetadata::end_keywords() const
return _implementation->keywords.end();
}
-VersionMetadata::ProvideIterator
-VersionMetadata::begin_provide() const
-{
- if (_implementation->provide.empty())
- {
- Tokeniser<delim_kind::AnyOfTag, delim_mode::DelimiterTag> tokeniser(" \t\n");
- tokeniser.tokenise(get(vmk_provide),
- create_inserter<QualifiedPackageName>(
- std::inserter(_implementation->provide, _implementation->provide.begin())));
- }
-
- return _implementation->provide.begin();
-}
-
-VersionMetadata::ProvideIterator
-VersionMetadata::end_provide() const
-{
- return _implementation->provide.end();
-}
-
diff --git a/paludis/version_metadata.hh b/paludis/version_metadata.hh
index 7dadb1a..a35c2d0 100644
--- a/paludis/version_metadata.hh
+++ b/paludis/version_metadata.hh
@@ -88,10 +88,6 @@ namespace paludis
typedef std::set<KeywordName>::const_iterator KeywordIterator;
KeywordIterator begin_keywords() const;
KeywordIterator end_keywords() const;
-
- typedef std::set<QualifiedPackageName>::const_iterator ProvideIterator;
- ProvideIterator begin_provide() const;
- ProvideIterator end_provide() const;
///}
/**
diff --git a/src/command_line.cc b/src/command_line.cc
index 3cab207..92b2fac 100644
--- a/src/command_line.cc
+++ b/src/command_line.cc
@@ -51,8 +51,9 @@ CommandLine::CommandLine() :
"as-needed"),
a_dl_drop_self_circular(&dl_args, "dl-drop-self-circular", '\0', "Drop self-circular dependencies"),
a_dl_drop_circular(&dl_args, "dl-drop-circular", '\0', "Drop circular dependencies"),
- a_dl_ignore_installed(&dl_args, "dl-ignore-installed", '\0', "Ignore installed packages"),
- a_dl_recursive_deps(&dl_args, "dl-recursive-deps", '\0', "Check dependencies for installed packages"),
+ a_dl_drop_all(&dl_args, "dl-drop-all", '0', "Drop all dependencies"),
+ a_dl_ignore_installed(&dl_args, "dl-ignore-installed", 'e', "Ignore installed packages"),
+ a_dl_recursive_deps(&dl_args, "dl-recursive-deps", 'D', "Check dependencies for installed packages"),
a_dl_max_stack_depth(&dl_args, "dl-max-stack-depth", '\0', "Maximum stack depth (default 100)")
{
a_dl_max_stack_depth.set_argument(100);
diff --git a/src/command_line.hh b/src/command_line.hh
index d91aa23..3bf1715 100644
--- a/src/command_line.hh
+++ b/src/command_line.hh
@@ -128,6 +128,9 @@ class CommandLine :
/// --dl-drop-circular
paludis::args::SwitchArg a_dl_drop_circular;
+ /// --dl-drop-all
+ paludis::args::SwitchArg a_dl_drop_all;
+
/// --dl-ignore-installed
paludis::args::SwitchArg a_dl_ignore_installed;
diff --git a/src/install.cc b/src/install.cc
index 73f3255..265c4cd 100644
--- a/src/install.cc
+++ b/src/install.cc
@@ -59,6 +59,7 @@ do_install()
p::DepList dep_list(env);
dep_list.set_drop_self_circular(CommandLine::get_instance()->a_dl_drop_self_circular.specified());
dep_list.set_drop_circular(CommandLine::get_instance()->a_dl_drop_circular.specified());
+ dep_list.set_drop_all(CommandLine::get_instance()->a_dl_drop_all.specified());
dep_list.set_ignore_installed(CommandLine::get_instance()->a_dl_ignore_installed.specified());
dep_list.set_recursive_deps(CommandLine::get_instance()->a_dl_recursive_deps.specified());
dep_list.set_max_stack_depth(CommandLine::get_instance()->a_dl_max_stack_depth.argument());