aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-01-24 19:35:26 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-01-24 19:35:26 +0000
commita82b71c2bb18273c88778a24b4309847a6b35c04 (patch)
treede433b7e760ba95d6230dffb9a0c3c01b3af450d
parent4ed226241d1e3a1d30b1ccb706e2cacb9aabc6f9 (diff)
downloadpaludis-a82b71c2bb18273c88778a24b4309847a6b35c04.tar.gz
paludis-a82b71c2bb18273c88778a24b4309847a6b35c04.tar.xz
Rewrite || ( ) dep atoms. Fixes: ticket:14
-rw-r--r--paludis/dep_atom.cc14
-rw-r--r--paludis/dep_atom.hh18
-rw-r--r--paludis/dep_list/Makefile.am18
-rw-r--r--paludis/dep_list/dep_list.cc18
-rw-r--r--paludis/dep_list/range_rewriter.cc103
-rw-r--r--paludis/dep_list/range_rewriter.hh55
-rw-r--r--paludis/dep_list/range_rewriter_TEST.cc53
7 files changed, 273 insertions, 6 deletions
diff --git a/paludis/dep_atom.cc b/paludis/dep_atom.cc
index 361c0f0..b6e641a 100644
--- a/paludis/dep_atom.cc
+++ b/paludis/dep_atom.cc
@@ -143,13 +143,15 @@ PackageDepAtom::PackageDepAtom(const PackageDepAtom & other) :
StringDepAtom(stringify(other)),
Visitable<PackageDepAtom, DepAtomVisitorTypes>(other),
_package(other._package),
- _version_requirements(other._version_requirements),
+ _version_requirements(new VersionRequirements::Concrete),
_version_requirements_mode(other._version_requirements_mode),
_slot(other._slot),
_repository(other._repository),
_use_requirements(other._use_requirements),
_tag(other._tag)
{
+ std::copy(other._version_requirements->begin(), other._version_requirements->end(),
+ _version_requirements->inserter());
}
PackageDepAtom::PackageDepAtom(const std::string & ss) :
@@ -325,14 +327,20 @@ paludis::operator<< (std::ostream & s, const PackageDepAtom & a)
if (a.version_requirements_ptr())
{
- bool need_comma(false);
+ bool need_comma(false), need_hyphen(true);
for (VersionRequirements::Iterator r(a.version_requirements_ptr()->begin()),
r_end(a.version_requirements_ptr()->end()) ; r != r_end ; ++r)
{
if (need_comma)
s << ",";
- s << "-" << r->version_spec;
+ if (need_hyphen)
+ {
+ s << "-";
+ need_hyphen = false;
+ }
+
+ s << r->version_spec;
if (r->version_operator == vo_equal_star)
s << "*";
diff --git a/paludis/dep_atom.hh b/paludis/dep_atom.hh
index 431d1c8..eadae34 100644
--- a/paludis/dep_atom.hh
+++ b/paludis/dep_atom.hh
@@ -335,6 +335,8 @@ namespace paludis
UseRequirements::Pointer _use_requirements;
DepTag::ConstPointer _tag;
+ const PackageDepAtom & operator= (const PackageDepAtom &);
+
public:
///\name Basic operations
///\{
@@ -375,6 +377,14 @@ namespace paludis
}
/**
+ * Fetch the version requirements (may be a zero pointer).
+ */
+ VersionRequirements::Pointer version_requirements_ptr()
+ {
+ return _version_requirements;
+ }
+
+ /**
* Fetch the version requirements mode.
*/
VersionRequirementsMode version_requirements_mode() const
@@ -383,6 +393,14 @@ namespace paludis
}
/**
+ * Set the version requirements mode.
+ */
+ void set_version_requirements_mode(const VersionRequirementsMode m)
+ {
+ _version_requirements_mode = m;
+ }
+
+ /**
* Fetch the slot name (may be a zero pointer).
*/
CountedPtr<SlotName, count_policy::ExternalCountTag> slot_ptr() const
diff --git a/paludis/dep_list/Makefile.am b/paludis/dep_list/Makefile.am
index 3120326..5fb8b02 100644
--- a/paludis/dep_list/Makefile.am
+++ b/paludis/dep_list/Makefile.am
@@ -17,13 +17,15 @@ paludis_dep_list_include_HEADERS = \
exceptions.hh \
options.hh \
dep_list-sr.hh \
- uninstall_list-sr.hh
+ uninstall_list-sr.hh \
+ range_rewriter.hh
libpaludisdeplist_la_SOURCES = \
options.cc options.hh \
exceptions.cc exceptions.hh \
dep_list.cc dep_list.hh \
- uninstall_list.cc uninstall_list.hh
+ uninstall_list.cc uninstall_list.hh \
+ range_rewriter.cc range_rewriter.hh
libpaludisdeplist_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
@@ -50,13 +52,15 @@ EXTRA_DIST = \
dep_list_TEST.hh \
dep_list_TEST_blockers.cc \
uninstall_list_TEST.cc \
+ range_rewriter_TEST.cc \
dep_list.sr dep_list-sr.hh dep_list-sr.cc \
uninstall_list.sr uninstall_list-sr.hh uninstall_list-sr.cc
TESTS = \
dep_list_TEST \
dep_list_TEST_blockers \
- uninstall_list_TEST
+ uninstall_list_TEST \
+ range_rewriter_TEST
TESTS_ENVIRONMENT = env \
PALUDIS_EBUILD_DIR="$(top_srcdir)/ebuild/" \
@@ -100,6 +104,14 @@ uninstall_list_TEST_LDADD = \
$(top_builddir)/paludis/libpaludis.la \
$(top_builddir)/paludis/util/libpaludisutil.la
+range_rewriter_TEST_SOURCES = range_rewriter_TEST.cc
+range_rewriter_TEST_LDADD = \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ libpaludisdeplist.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
built-sources : $(BUILT_SOURCES)
for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
diff --git a/paludis/dep_list/dep_list.cc b/paludis/dep_list/dep_list.cc
index 91e28b6..1e8213b 100644
--- a/paludis/dep_list/dep_list.cc
+++ b/paludis/dep_list/dep_list.cc
@@ -19,8 +19,10 @@
#include <paludis/dep_atom.hh>
#include <paludis/dep_atom_flattener.hh>
+#include <paludis/dep_atom_pretty_printer.hh>
#include <paludis/dep_list/dep_list.hh>
#include <paludis/dep_list/exceptions.hh>
+#include <paludis/dep_list/range_rewriter.hh>
#include <paludis/match_package.hh>
#include <paludis/hashed_containers.hh>
#include <paludis/util/collection_concrete.hh>
@@ -412,6 +414,14 @@ DepList::QueryVisitor::visit(const AnyDepAtom * const a)
std::copy(a->begin(), a->end(), filter_inserter(std::back_inserter(viable_children),
IsViableAnyDepAtomChild(d->_imp->env, d->_imp->current_pde())));
+ RangeRewriter r;
+ std::for_each(viable_children.begin(), viable_children.end(), accept_visitor(&r));
+ if (r.atom())
+ {
+ viable_children.clear();
+ viable_children.push_back(r.atom());
+ }
+
result = true;
for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
c_end(viable_children.end()) ; c != c_end ; ++c)
@@ -762,6 +772,14 @@ DepList::AddVisitor::visit(const AnyDepAtom * const a)
if (viable_children.empty())
return;
+ RangeRewriter r;
+ std::for_each(viable_children.begin(), viable_children.end(), accept_visitor(&r));
+ if (r.atom())
+ {
+ viable_children.clear();
+ viable_children.push_back(r.atom());
+ }
+
/* see if any of our children is already installed. if any is, add it so that
* any upgrades kick in */
for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
diff --git a/paludis/dep_list/range_rewriter.cc b/paludis/dep_list/range_rewriter.cc
new file mode 100644
index 0000000..053d5ae
--- /dev/null
+++ b/paludis/dep_list/range_rewriter.cc
@@ -0,0 +1,103 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.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 version 2, as published by the Free Software Foundation.
+ *
+ * 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 "range_rewriter.hh"
+
+using namespace paludis;
+
+RangeRewriter::RangeRewriter() :
+ _atom(0),
+ _invalid(false)
+{
+}
+
+RangeRewriter::~RangeRewriter()
+{
+}
+
+void
+RangeRewriter::visit(const AllDepAtom * a)
+{
+ if (a->begin() != a->end())
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const AnyDepAtom * a)
+{
+ if (a->begin() != a->end())
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const UseDepAtom *)
+{
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const PlainTextDepAtom *)
+{
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const PackageDepAtom * a)
+{
+ if (_invalid)
+ return;
+
+ if (a->use_requirements_ptr() || a->slot_ptr() || a->use_requirements_ptr() || ! a->version_requirements_ptr())
+ {
+ _invalid = true;
+ return;
+ }
+
+ if (a->version_requirements_mode() != vr_or && 1 != std::distance(a->version_requirements_ptr()->begin(),
+ a->version_requirements_ptr()->end()))
+ {
+ _invalid = true;
+ return;
+ }
+
+ if (_atom)
+ {
+ if (a->package() != _atom->package())
+ {
+ _invalid = true;
+ return;
+ }
+
+ for (VersionRequirements::Iterator v(a->version_requirements_ptr()->begin()),
+ v_end(a->version_requirements_ptr()->end()) ; v != v_end ; ++v)
+ _atom->version_requirements_ptr()->push_back(*v);
+ }
+ else
+ {
+ _atom.assign(new PackageDepAtom(*a));
+ _atom->set_version_requirements_mode(vr_or);
+ }
+}
+
+void
+RangeRewriter::visit(const BlockDepAtom *)
+{
+ _invalid = true;
+}
+
diff --git a/paludis/dep_list/range_rewriter.hh b/paludis/dep_list/range_rewriter.hh
new file mode 100644
index 0000000..0d4e984
--- /dev/null
+++ b/paludis/dep_list/range_rewriter.hh
@@ -0,0 +1,55 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.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 version 2, as published by the Free Software Foundation.
+ *
+ * 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_LIST_RANGE_REWRITER_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_RANGE_REWRITER_HH 1
+
+#include <paludis/dep_atom.hh>
+
+namespace paludis
+{
+ class RangeRewriter :
+ public DepAtomVisitorTypes::ConstVisitor
+ {
+ private:
+ PackageDepAtom::Pointer _atom;
+ bool _invalid;
+
+ public:
+ RangeRewriter();
+ virtual ~RangeRewriter();
+
+ PackageDepAtom::ConstPointer atom() const
+ {
+ if (_invalid)
+ return PackageDepAtom::ConstPointer(0);
+
+ return _atom;
+ }
+
+ void visit(const AllDepAtom *);
+ void visit(const AnyDepAtom *);
+ void visit(const UseDepAtom *);
+ void visit(const PlainTextDepAtom *);
+ void visit(const PackageDepAtom *);
+ void visit(const BlockDepAtom *);
+ };
+}
+
+#endif
diff --git a/paludis/dep_list/range_rewriter_TEST.cc b/paludis/dep_list/range_rewriter_TEST.cc
new file mode 100644
index 0000000..6ef8b5e
--- /dev/null
+++ b/paludis/dep_list/range_rewriter_TEST.cc
@@ -0,0 +1,53 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.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 version 2, as published by the Free Software Foundation.
+ *
+ * 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 <paludis/dep_list/range_rewriter.hh>
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_atom_pretty_printer.hh>
+#include <paludis/portage_dep_parser.hh>
+
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+
+using namespace test;
+using namespace paludis;
+
+namespace test_cases
+{
+ struct RangeRewriterTestCase :
+ TestCase
+ {
+ RangeRewriterTestCase() : TestCase("range rewriter") { }
+
+ void run()
+ {
+ AllDepAtom::ConstPointer p(PortageDepParser::parse_depend("=a/b-1 =a/b-2"));
+
+ RangeRewriter r;
+ TEST_CHECK(! r.atom());
+ std::for_each(p->begin(), p->end(), accept_visitor(&r));
+ TEST_CHECK(r.atom());
+
+ DepAtomPrettyPrinter w(0, false);
+ r.atom()->accept(&w);
+ TEST_CHECK_STRINGIFY_EQUAL(w, "=|=a/b-1,2 ");
+ }
+ } test_range_rewriter;
+}
+