aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-18 05:49:29 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-18 05:49:29 +0000
commitcf84ad282eca676d3411b4edf548eadd82d2731e (patch)
treea16b53c97eefd67cbe080fb424c555c380ef8fea
parente4f407ecbc124d1af8da8a168e2684e85ef77298 (diff)
downloadpaludis-cf84ad282eca676d3411b4edf548eadd82d2731e.tar.gz
paludis-cf84ad282eca676d3411b4edf548eadd82d2731e.tar.xz
Separate Dep and Nest heirarchies, since they're not really the same. Share the lexer.
-rw-r--r--paludis/dep_lexer.cc2
-rw-r--r--paludis/dep_lexer.hh2
-rw-r--r--paludis/dep_lexer_TEST.cc14
-rw-r--r--paludis/dep_list.cc32
-rw-r--r--paludis/dep_parser.cc27
-rw-r--r--paludis/dep_parser.hh25
-rw-r--r--paludis/files.m44
-rw-r--r--paludis/nest_atom.cc72
-rw-r--r--paludis/nest_atom.hh215
-rw-r--r--paludis/nest_atom_flattener.cc (renamed from paludis/dep_atom_flattener.cc)36
-rw-r--r--paludis/nest_atom_flattener.hh (renamed from paludis/dep_atom_flattener.hh)34
-rw-r--r--paludis/nest_parser.cc212
-rw-r--r--paludis/nest_parser.hh85
13 files changed, 648 insertions, 112 deletions
diff --git a/paludis/dep_lexer.cc b/paludis/dep_lexer.cc
index e593b46..9741d41 100644
--- a/paludis/dep_lexer.cc
+++ b/paludis/dep_lexer.cc
@@ -67,6 +67,6 @@ DepLexer::DepLexer(const std::string & s)
else if ('?' == (*t)[t->length() - 1])
_tokens.push_back(std::make_pair(dpl_use_flag, *t));
else
- _tokens.push_back(std::make_pair(dpl_package, *t));
+ _tokens.push_back(std::make_pair(dpl_text, *t));
}
}
diff --git a/paludis/dep_lexer.hh b/paludis/dep_lexer.hh
index 2140cf7..77ea48e 100644
--- a/paludis/dep_lexer.hh
+++ b/paludis/dep_lexer.hh
@@ -74,7 +74,7 @@ namespace paludis
enum DepLexerLexeme
{
dpl_whitespace, ///< whitespace
- dpl_package, ///< a package name
+ dpl_text, ///< a package or item name
dpl_use_flag, ///< a use flag
dpl_double_bar, ///< a double bar ('any' marker)
dpl_open_paren, ///< open paren
diff --git a/paludis/dep_lexer_TEST.cc b/paludis/dep_lexer_TEST.cc
index 71a09a8..742391e 100644
--- a/paludis/dep_lexer_TEST.cc
+++ b/paludis/dep_lexer_TEST.cc
@@ -84,7 +84,7 @@ namespace test_cases
DepLexer l("app-editors/vim");
DepLexer::Iterator i(l.begin());
TEST_CHECK(i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_package);
+ TEST_CHECK_EQUAL(i->first, dpl_text);
TEST_CHECK_EQUAL(i->second, "app-editors/vim");
TEST_CHECK(++i == l.end());
}
@@ -105,7 +105,7 @@ namespace test_cases
DepLexer::Iterator i(l.begin());
TEST_CHECK(i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_package);
+ TEST_CHECK_EQUAL(i->first, dpl_text);
TEST_CHECK_EQUAL(i->second, "app-editors/vim");
TEST_CHECK(++i != l.end());
@@ -113,7 +113,7 @@ namespace test_cases
TEST_CHECK_EQUAL(i->second, " ");
TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_package);
+ TEST_CHECK_EQUAL(i->first, dpl_text);
TEST_CHECK_EQUAL(i->second, "app-misc/hilite");
TEST_CHECK(++i != l.end());
@@ -121,7 +121,7 @@ namespace test_cases
TEST_CHECK_EQUAL(i->second, " \n");
TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_package);
+ TEST_CHECK_EQUAL(i->first, dpl_text);
TEST_CHECK_EQUAL(i->second, "sys-apps/findutils");
TEST_CHECK(++i == l.end());
@@ -159,7 +159,7 @@ namespace test_cases
TEST_CHECK_EQUAL(i->second, " ");
TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_package);
+ TEST_CHECK_EQUAL(i->first, dpl_text);
TEST_CHECK_EQUAL(i->second, "one/one");
TEST_CHECK(++i != l.end());
@@ -167,7 +167,7 @@ namespace test_cases
TEST_CHECK_EQUAL(i->second, " ");
TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_package);
+ TEST_CHECK_EQUAL(i->first, dpl_text);
TEST_CHECK_EQUAL(i->second, "two/two");
TEST_CHECK(++i != l.end());
@@ -213,7 +213,7 @@ namespace test_cases
TEST_CHECK_EQUAL(i->second, " ");
TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_package);
+ TEST_CHECK_EQUAL(i->first, dpl_text);
TEST_CHECK_EQUAL(i->second, "one/one");
TEST_CHECK(++i != l.end());
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index ff67db3..f22e667 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -19,7 +19,7 @@
#include "container_entry.hh"
#include "dep_atom.hh"
-#include "dep_atom_flattener.hh"
+#include "nest_atom_flattener.hh"
#include "dep_list.hh"
#include "dep_parser.hh"
#include "filter_insert_iterator.hh"
@@ -28,6 +28,9 @@
#include "join.hh"
#include "log.hh"
#include "match_package.hh"
+#include "nest_parser.hh"
+#include "nest_atom.hh"
+#include "nest_atom_flattener.hh"
#include "save.hh"
#include "stringify.hh"
@@ -382,9 +385,7 @@ DepList::visit(const PackageDepAtom * const p)
/// \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));
+ NestAtom::ConstPointer provide(NestParser::parse(metadata->get(vmk_provide)));
CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e(0);
@@ -395,21 +396,22 @@ DepList::visit(const PackageDepAtom * const p)
_implementation->current_package->get<dle_version>(),
_implementation->current_package->get<dle_repository>()));
- DepAtomFlattener f(_implementation->environment, e.raw_pointer(), provide);
+ NestAtomFlattener f(_implementation->environment, e.raw_pointer(), provide);
- for (DepAtomFlattener::Iterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
+ for (NestAtomFlattener::Iterator p(f.begin()), p_end(f.end()) ; p != p_end ; ++p)
{
+ PackageDepAtom pp(QualifiedPackageName((*p)->text()));
if (_implementation->merge_list.end() != std::find_if(
_implementation->merge_list.begin(), _implementation->merge_list.end(),
DepListEntryMatcher(
- _implementation->environment->package_database().raw_pointer(), **p)))
+ _implementation->environment->package_database().raw_pointer(), pp)))
continue;
VersionMetadata::Pointer p_metadata(new VersionMetadata);
p_metadata->set(vmk_slot, merge_entry->get<dle_metadata>()->get(vmk_slot));
p_metadata->set(vmk_virtual, stringify(merge_entry->get<dle_name>()));
_implementation->merge_list.insert(next(merge_entry),
- DepListEntry((*p)->package(), merge_entry->get<dle_version>(),
+ DepListEntry(pp.package(), merge_entry->get<dle_version>(),
p_metadata, merge_entry->get<dle_repository>(), true, true, true));
}
}
@@ -596,12 +598,8 @@ DepList::visit(const BlockDepAtom * const d)
continue;
}
- DepParserOptions dep_parser_options;
- dep_parser_options.set(dpo_qualified_package_names);
-
- DepAtom::ConstPointer provide(DepParser::parse(
- _implementation->current_package->get<dle_metadata>()->get(vmk_provide),
- dep_parser_options));
+ NestAtom::ConstPointer provide(NestParser::parse(
+ _implementation->current_package->get<dle_metadata>()->get(vmk_provide)));
CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e(0);
@@ -612,12 +610,12 @@ DepList::visit(const BlockDepAtom * const d)
_implementation->current_package->get<dle_version>(),
_implementation->current_package->get<dle_repository>()));
- DepAtomFlattener f(_implementation->environment, e.raw_pointer(), provide);
+ NestAtomFlattener f(_implementation->environment, e.raw_pointer(), provide);
bool skip(false);
- for (IndirectIterator<DepAtomFlattener::Iterator, const PackageDepAtom> i(f.begin()),
+ for (IndirectIterator<NestAtomFlattener::Iterator, const TextNestAtom> i(f.begin()),
i_end(f.end()) ; i != i_end ; ++i)
- if (i->package() == d->blocked_atom()->package())
+ if (QualifiedPackageName(i->text()) == d->blocked_atom()->package())
{
skip = true;
break;
diff --git a/paludis/dep_parser.cc b/paludis/dep_parser.cc
index d89acdf..c7fc225 100644
--- a/paludis/dep_parser.cc
+++ b/paludis/dep_parser.cc
@@ -48,7 +48,7 @@ enum DepParserState
};
CompositeDepAtom::ConstPointer
-DepParser::parse(const std::string & s, const DepParserOptions & opts)
+DepParser::parse(const std::string & s)
{
Context context("When parsing dependency string '" + s + "':");
@@ -75,7 +75,7 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
case dpl_whitespace:
continue;
- case dpl_package:
+ case dpl_text:
{
if (i->second.empty())
throw DepStringParseError(i->second, "Empty package name");
@@ -110,10 +110,6 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
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);
@@ -160,7 +156,7 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
state = dps_had_double_bar_space;
continue;
- case dpl_package:
+ case dpl_text:
case dpl_use_flag:
case dpl_double_bar:
case dpl_open_paren:
@@ -183,7 +179,7 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
continue;
case dpl_whitespace:
- case dpl_package:
+ case dpl_text:
case dpl_use_flag:
case dpl_double_bar:
case dpl_close_paren:
@@ -203,7 +199,7 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
state = dps_initial;
continue;
- case dpl_package:
+ case dpl_text:
case dpl_use_flag:
case dpl_double_bar:
case dpl_open_paren:
@@ -224,7 +220,7 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
state = dps_had_use_flag_space;
continue;
- case dpl_package:
+ case dpl_text:
case dpl_use_flag:
case dpl_double_bar:
case dpl_open_paren:
@@ -246,7 +242,7 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
continue;
case dpl_whitespace:
- case dpl_package:
+ case dpl_text:
case dpl_use_flag:
case dpl_double_bar:
case dpl_close_paren:
@@ -272,12 +268,3 @@ DepParser::parse(const std::string & s, const DepParserOptions & opts)
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 a82adae..2114a26 100644
--- a/paludis/dep_parser.hh
+++ b/paludis/dep_parser.hh
@@ -25,7 +25,6 @@
#include <paludis/instantiation_policy.hh>
#include <paludis/exception.hh>
#include <paludis/dep_lexer.hh>
-#include <bitset>
#include <string>
/** \file
@@ -68,40 +67,18 @@ 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:
- /**
- * Default options for parse.
- */
- static DepParserOptions default_options();
-
public:
/**
* Parse a given dependency string, and return an appropriate
* DepAtom tree.
*/
- static CompositeDepAtom::ConstPointer parse(const std::string & s,
- const DepParserOptions & opts = default_options());
+ static CompositeDepAtom::ConstPointer parse(const std::string & s);
};
}
diff --git a/paludis/files.m4 b/paludis/files.m4
index b544aa6..120f882 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -23,7 +23,6 @@ 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_pretty_printer', `hh', `cc')
add(`dep_lexer', `hh', `cc', `test')
add(`dep_list', `hh', `cc', `test')
@@ -49,6 +48,9 @@ add(`line_config_file', `hh', `cc', `test')
add(`log', `hh', `cc', `test')
add(`mask_reasons', `hh', `cc')
add(`match_package', `hh', `cc')
+add(`nest_atom', `hh', `cc')
+add(`nest_atom_flattener', `hh', `cc')
+add(`nest_parser', `hh', `cc')
add(`package_database', `hh', `cc', `test')
add(`package_name_part', `hh', `cc', `test')
add(`paludis', `hh', `cc')
diff --git a/paludis/nest_atom.cc b/paludis/nest_atom.cc
new file mode 100644
index 0000000..7ed4184
--- /dev/null
+++ b/paludis/nest_atom.cc
@@ -0,0 +1,72 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 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 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 "nest_atom.hh"
+
+using namespace paludis;
+
+NestAtom::NestAtom()
+{
+}
+
+NestAtom::~NestAtom()
+{
+}
+
+const UseNestAtom *
+NestAtom::as_use_nest_atom() const
+{
+ return 0;
+}
+
+CompositeNestAtom::CompositeNestAtom()
+{
+}
+
+void
+CompositeNestAtom::add_child(NestAtom::ConstPointer c)
+{
+ _children.push_back(c);
+}
+
+AllNestAtom::AllNestAtom()
+{
+}
+
+UseNestAtom::UseNestAtom(const UseFlagName & flag, bool inverse) :
+ _flag(flag),
+ _inverse(inverse)
+{
+}
+
+const UseNestAtom *
+UseNestAtom::as_use_nest_atom() const
+{
+ return this;
+}
+
+TextNestAtom::TextNestAtom(const std::string & text) :
+ _text(text)
+{
+}
+
+TextNestAtom::~TextNestAtom()
+{
+}
+
diff --git a/paludis/nest_atom.hh b/paludis/nest_atom.hh
new file mode 100644
index 0000000..c44a02a
--- /dev/null
+++ b/paludis/nest_atom.hh
@@ -0,0 +1,215 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 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 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_NEST_ATOM_HH
+#define PALUDIS_GUARD_PALUDIS_NEST_ATOM_HH 1
+
+#include <paludis/attributes.hh>
+#include <paludis/composite_pattern.hh>
+#include <paludis/counted_ptr.hh>
+#include <paludis/instantiation_policy.hh>
+#include <paludis/slot_name.hh>
+#include <paludis/use_flag_name.hh>
+#include <paludis/visitor.hh>
+#include <list>
+
+/** \file
+ * Declarations for the NestAtom classes.
+ *
+ * \ingroup DepResolver
+ */
+
+namespace paludis
+{
+ class NestAtom;
+ class CompositeNestAtom;
+ class TextNestAtom;
+ class AllNestAtom;
+ class UseNestAtom;
+
+ /**
+ * Visitor types for a visitor that can visit a NestAtom heirarchy.
+ */
+ typedef VisitorTypes<TextNestAtom *, AllNestAtom *, UseNestAtom *> NestAtomVisitorTypes;
+
+ /**
+ * Base class for a dependency atom.
+ *
+ * \ingroup DepResolver
+ */
+ class NestAtom :
+ public virtual VisitableInterface<NestAtomVisitorTypes>,
+ public virtual Composite<NestAtom, CompositeNestAtom>,
+ private InstantiationPolicy<NestAtom, instantiation_method::NonCopyableTag>,
+ public InternalCounted<NestAtom>
+ {
+ protected:
+ NestAtom();
+
+ public:
+ virtual ~NestAtom();
+
+ /**
+ * Return us as a UseNestAtom, or 0 if we are not a
+ * UseNestAtom.
+ */
+ virtual const UseNestAtom * as_use_nest_atom() const PALUDIS_ATTRIBUTE((pure));
+ };
+
+ /**
+ * Class for nest atoms that have a number of child nest
+ * atoms.
+ *
+ * \ingroup DepResolver
+ */
+ class CompositeNestAtom :
+ public NestAtom,
+ public virtual Composite<NestAtom, CompositeNestAtom>
+ {
+ private:
+ std::list<NestAtom::ConstPointer> _children;
+
+ protected:
+ /**
+ * Constructor.
+ */
+ CompositeNestAtom();
+
+ public:
+ /**
+ * Append a child to our collection.
+ */
+ virtual void add_child(NestAtom::ConstPointer);
+
+ /**
+ * Iterator for iterating over our children.
+ */
+ typedef std::list<NestAtom::ConstPointer>::const_iterator Iterator;
+
+ /**
+ * Iterator to the start of our children.
+ */
+ Iterator begin() const
+ {
+ return _children.begin();
+ }
+
+ /**
+ * Iterator to past the end of our children.
+ */
+ Iterator end() const
+ {
+ return _children.end();
+ }
+
+ typedef CountedPtr<CompositeNestAtom, count_policy::InternalCountTag> Pointer;
+ typedef CountedPtr<const CompositeNestAtom, count_policy::InternalCountTag> ConstPointer;
+ };
+
+ /**
+ * Represents a ( first second third ) or top level group of nest
+ * atoms.
+ *
+ * \ingroup DepResolver
+ */
+ class AllNestAtom :
+ public CompositeNestAtom,
+ public Visitable<AllNestAtom, NestAtomVisitorTypes>
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ AllNestAtom();
+ };
+
+ /**
+ * Represents a use? ( ) dependency atom.
+ *
+ * \ingroup DepResolver
+ */
+ class UseNestAtom :
+ public CompositeNestAtom,
+ public Visitable<UseNestAtom, NestAtomVisitorTypes>
+ {
+ private:
+ const UseFlagName _flag;
+ const bool _inverse;
+
+ public:
+ /**
+ * Constructor.
+ */
+ UseNestAtom(const UseFlagName &, bool);
+
+ /**
+ * Fetch our use flag name.
+ */
+ const UseFlagName & flag() const
+ {
+ return _flag;
+ }
+
+ /**
+ * Fetch whether we are a ! flag.
+ */
+ bool inverse() const
+ {
+ return _inverse;
+ }
+
+ virtual const UseNestAtom * as_use_nest_atom() const PALUDIS_ATTRIBUTE((pure));
+ };
+
+ /**
+ * A TextNestAtom represents a text entry (for example, a URL for
+ * SRC_URI).
+ *
+ * \ingroup DepResolver
+ */
+ class TextNestAtom :
+ public NestAtom,
+ public Visitable<TextNestAtom, NestAtomVisitorTypes>
+ {
+ private:
+ std::string _text;
+
+ public:
+ TextNestAtom(const std::string & text);
+
+ /**
+ * Destructor.
+ */
+ ~TextNestAtom();
+
+ /**
+ * Fetch the package name.
+ */
+ const std::string & text() const
+ {
+ return _text;
+ }
+
+ typedef CountedPtr<TextNestAtom, count_policy::InternalCountTag> Pointer;
+ typedef CountedPtr<const TextNestAtom, count_policy::InternalCountTag> ConstPointer;
+ };
+
+}
+
+#endif
diff --git a/paludis/dep_atom_flattener.cc b/paludis/nest_atom_flattener.cc
index 96e34a5..5943654 100644
--- a/paludis/dep_atom_flattener.cc
+++ b/paludis/nest_atom_flattener.cc
@@ -17,15 +17,15 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "dep_atom_flattener.hh"
-#include "dep_atom.hh"
+#include "nest_atom_flattener.hh"
+#include "nest_atom.hh"
using namespace paludis;
-DepAtomFlattener::DepAtomFlattener(
+NestAtomFlattener::NestAtomFlattener(
const Environment * const env,
const PackageDatabaseEntry * const pkg,
- DepAtom::ConstPointer a) :
+ NestAtom::ConstPointer a) :
_env(env),
_pkg(pkg),
_a(a),
@@ -33,46 +33,36 @@ DepAtomFlattener::DepAtomFlattener(
{
}
-DepAtomFlattener::~DepAtomFlattener()
+NestAtomFlattener::~NestAtomFlattener()
{
}
-DepAtomFlattener::Iterator
-DepAtomFlattener::begin()
+NestAtomFlattener::Iterator
+NestAtomFlattener::begin()
{
if (! _done)
{
- _a->accept(static_cast<DepAtomVisitorTypes::ConstVisitor *>(this));
+ _a->accept(static_cast<NestAtomVisitorTypes::ConstVisitor *>(this));
_done = true;
}
return _atoms.begin();
}
-void DepAtomFlattener::visit(const AllDepAtom * a)
+void NestAtomFlattener::visit(const AllNestAtom * a)
{
std::for_each(a->begin(), a->end(), accept_visitor(
- static_cast<DepAtomVisitorTypes::ConstVisitor *>(this)));
+ static_cast<NestAtomVisitorTypes::ConstVisitor *>(this)));
}
-void DepAtomFlattener::visit(const AnyDepAtom *)
-{
- throw paludis::InternalError(PALUDIS_HERE, "Not allowed an AnyDepAtom");
-}
-
-void DepAtomFlattener::visit(const UseDepAtom * u)
+void NestAtomFlattener::visit(const UseNestAtom * 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");
+ static_cast<NestAtomVisitorTypes::ConstVisitor *>(this)));
}
-void DepAtomFlattener::visit(const PackageDepAtom * p)
+void NestAtomFlattener::visit(const TextNestAtom * p)
{
_atoms.push_back(p);
}
diff --git a/paludis/dep_atom_flattener.hh b/paludis/nest_atom_flattener.hh
index d2a3369..107a6ea 100644
--- a/paludis/dep_atom_flattener.hh
+++ b/paludis/nest_atom_flattener.hh
@@ -17,11 +17,11 @@
* 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
+#ifndef PALUDIS_GUARD_PALUDIS_NEST_ATOM_FLATTENER_HH
+#define PALUDIS_GUARD_PALUDIS_NEST_ATOM_FLATTENER_HH 1
#include <paludis/attributes.hh>
-#include <paludis/dep_atom.hh>
+#include <paludis/nest_atom.hh>
#include <paludis/environment.hh>
#include <paludis/instantiation_policy.hh>
#include <paludis/package_database.hh>
@@ -30,51 +30,49 @@
namespace paludis
{
/**
- * Extract the enabled components of a dep heirarchy for a particular
+ * Extract the enabled components of a nest heirarchy for a particular
* package.
*/
- class DepAtomFlattener :
- private InstantiationPolicy<DepAtomFlattener, instantiation_method::NonCopyableTag>,
- protected DepAtomVisitorTypes::ConstVisitor
+ class NestAtomFlattener :
+ private InstantiationPolicy<NestAtomFlattener, instantiation_method::NonCopyableTag>,
+ protected NestAtomVisitorTypes::ConstVisitor
{
private:
const Environment * const _env;
const PackageDatabaseEntry * const _pkg;
- DepAtom::ConstPointer _a;
+ NestAtom::ConstPointer _a;
- mutable std::list<const PackageDepAtom *> _atoms;
+ mutable std::list<const TextNestAtom *> _atoms;
mutable bool _done;
protected:
///\name Visit methods
///{
- 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 *);
+ void visit(const AllNestAtom *);
+ void visit(const UseNestAtom *);
+ void visit(const TextNestAtom *);
///}
public:
/**
* Constructor.
*/
- DepAtomFlattener(const Environment * const,
+ NestAtomFlattener(const Environment * const,
const PackageDatabaseEntry * const,
- const DepAtom::ConstPointer);
+ const NestAtom::ConstPointer);
/**
* Destructor.
*/
- ~DepAtomFlattener();
+ ~NestAtomFlattener();
/**
* Iterate over our dep atoms.
*/
- typedef std::list<const PackageDepAtom *>::const_iterator Iterator;
+ typedef std::list<const TextNestAtom *>::const_iterator Iterator;
/**
* Iterator to the start of our dep atoms.
diff --git a/paludis/nest_parser.cc b/paludis/nest_parser.cc
new file mode 100644
index 0000000..c18e70a
--- /dev/null
+++ b/paludis/nest_parser.cc
@@ -0,0 +1,212 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 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 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 "exception.hh"
+#include "stringify.hh"
+#include "nest_atom.hh"
+#include "nest_parser.hh"
+#include "dep_lexer.hh"
+#include <stack>
+
+using namespace paludis;
+
+NestStringParseError::NestStringParseError(const std::string & d,
+ const std::string & m) throw () :
+ DepStringError(d, "in nest parse phase: " + m)
+{
+}
+
+NestStringNestingError::NestStringNestingError(const std::string & dep_string) throw () :
+ NestStringParseError(dep_string, "improperly balanced parentheses")
+{
+}
+
+enum NestParserState
+{
+ nps_initial,
+ nps_had_paren,
+ nps_had_use_flag,
+ nps_had_use_flag_space
+};
+
+CompositeNestAtom::ConstPointer
+NestParser::parse(const std::string & s)
+{
+ Context context("When parsing nest string '" + s + "':");
+
+ std::stack<CompositeNestAtom::Pointer> stack;
+ stack.push(CompositeNestAtom::Pointer(new AllNestAtom));
+
+ NestParserState state(nps_initial);
+ DepLexer lexer(s);
+ DepLexer::Iterator i(lexer.begin()), i_end(lexer.end());
+
+ for ( ; i != i_end ; ++i)
+ {
+ Context context("When handling lexer token '" + i->second +
+ "' (" + stringify(i->first) + "):");
+ do
+ {
+ switch (state)
+ {
+ case nps_initial:
+ do
+ {
+ switch (i->first)
+ {
+ case dpl_whitespace:
+ continue;
+
+ case dpl_text:
+ {
+ if (i->second.empty())
+ throw NestStringParseError(i->second, "Empty item name");
+ stack.top()->add_child(NestAtom::Pointer(
+ new TextNestAtom(i->second)));
+ }
+ continue;
+
+ case dpl_open_paren:
+ {
+ CompositeNestAtom::Pointer a(new AllNestAtom);
+ stack.top()->add_child(a);
+ stack.push(a);
+ state = nps_had_paren;
+ }
+ continue;
+
+ case dpl_close_paren:
+ if (stack.empty())
+ throw NestStringNestingError(s);
+ stack.pop();
+ if (stack.empty())
+ throw NestStringNestingError(s);
+ state = nps_had_paren;
+ continue;
+
+ case dpl_double_bar:
+ throw NestStringParseError(s, "|| not allowed");
+
+ case dpl_use_flag:
+ {
+ std::string f(i->second);
+ bool inv(f.length() && ('!' == f.at(0)));
+ if (inv)
+ f.erase(0, 1);
+
+ if (f.empty())
+ throw NestStringParseError(s,
+ "Bad use flag name '" + i->second + "'");
+ if ('?' != f.at(f.length() - 1))
+ throw NestStringParseError(s,
+ "Use flag name '" + i->second + "' missing '?'");
+
+ f.erase(f.length() - 1);
+ CompositeNestAtom::Pointer a(
+ new UseNestAtom(UseFlagName(f), inv));
+ stack.top()->add_child(a);
+ stack.push(a);
+ state = nps_had_use_flag;
+ }
+ continue;
+
+ }
+ throw InternalError(PALUDIS_HERE,
+ "nps_initial: i->first is " + stringify(i->first));
+
+ } while (0);
+ continue;
+
+ case nps_had_paren:
+ do
+ {
+ switch (i->first)
+ {
+ case dpl_whitespace:
+ state = nps_initial;
+ continue;
+
+ case dpl_text:
+ case dpl_use_flag:
+ case dpl_double_bar:
+ case dpl_open_paren:
+ case dpl_close_paren:
+ throw NestStringParseError(s, "Expected space after '(' or ')'");
+ }
+ throw InternalError(PALUDIS_HERE,
+ "nps_had_paren: i->first is " + stringify(i->first));
+ } while (0);
+ continue;
+
+ case nps_had_use_flag:
+ do
+ {
+ switch (i->first)
+ {
+ case dpl_whitespace:
+ state = nps_had_use_flag_space;
+ continue;
+
+ case dpl_text:
+ case dpl_use_flag:
+ case dpl_double_bar:
+ case dpl_open_paren:
+ case dpl_close_paren:
+ throw NestStringParseError(s, "Expected space after use flag");
+ }
+ throw InternalError(PALUDIS_HERE,
+ "nps_had_use_flag: i->first is " + stringify(i->first));
+ } while (0);
+ continue;
+
+ case nps_had_use_flag_space:
+ do
+ {
+ switch (i->first)
+ {
+ case dpl_open_paren:
+ state = nps_had_paren;
+ continue;
+
+ case dpl_whitespace:
+ case dpl_text:
+ case dpl_use_flag:
+ case dpl_double_bar:
+ case dpl_close_paren:
+ throw NestStringParseError(s, "Expected '(' after use flag");
+ }
+ throw InternalError(PALUDIS_HERE,
+ "nps_had_use_flag_space: i->first is " + stringify(i->first));
+ } while (0);
+ continue;
+ }
+ throw InternalError(PALUDIS_HERE,
+ "state is " + stringify(state));
+
+ } while (0);
+ }
+
+ if (stack.empty())
+ throw NestStringNestingError(s);
+ CompositeNestAtom::Pointer result(stack.top());
+ stack.pop();
+ if (! stack.empty())
+ throw NestStringNestingError(s);
+ return result;
+}
diff --git a/paludis/nest_parser.hh b/paludis/nest_parser.hh
new file mode 100644
index 0000000..1554393
--- /dev/null
+++ b/paludis/nest_parser.hh
@@ -0,0 +1,85 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 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 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_NEST_PARSER_HH
+#define PALUDIS_GUARD_PALUDIS_NEST_PARSER_HH 1
+
+#include <paludis/nest_atom.hh>
+#include <paludis/counted_ptr.hh>
+#include <paludis/instantiation_policy.hh>
+#include <paludis/exception.hh>
+#include <paludis/dep_lexer.hh>
+#include <string>
+
+/** \file
+ * Declarations for the NestParser class.
+ *
+ * \ingroup DepResolver
+ * \ingroup Exception
+ */
+
+namespace paludis
+{
+ /**
+ * A NestStringParseError is thrown if an error is encountered when parsing
+ * a dependency string.
+ *
+ * \ingroup Exception
+ * \ingroup DepResolver
+ */
+ class NestStringParseError : public DepStringError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ NestStringParseError(const std::string & dep_string,
+ const std::string & message) throw ();
+ };
+
+ /**
+ * A NestStringNestingError is thrown if a dependency string does not have
+ * properly balanced parentheses.
+ */
+ class NestStringNestingError : public NestStringParseError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ NestStringNestingError(const std::string & dep_string) throw ();
+ };
+
+ /**
+ * The NestParser converts string representations of a reduced nested
+ * string specification into a NestAtom instance.
+ */
+ class NestParser :
+ private InstantiationPolicy<NestParser, instantiation_method::NonInstantiableTag>
+ {
+ public:
+ /**
+ * Parse a given dependency string, and return an appropriate
+ * NestAtom tree.
+ */
+ static CompositeNestAtom::ConstPointer parse(const std::string & s);
+ };
+}
+
+#endif