Exheredludis/paludis/repositories/fake/dep_parser.cc
Wouter van Kesteren 82a9e92b64 throw() -> noexcept
Change-Id: I461abfda8b7297c1bd04f1090f8d58fa96364616
Reviewed-on: https://galileo.mailstation.de/gerrit/1892
Reviewed-by: Saleem Abdulrasool <compnerd@compnerd.org>
Reviewed-by: Kylie McClain <somasis@exherbo.org>
2015-08-21 17:19:40 +02:00

305 lines
13 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Ciaran McCreesh
*
* 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/repositories/fake/dep_parser.hh>
#include <paludis/util/options.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/elike_dep_parser.hh>
#include <paludis/elike_conditional_dep_spec.hh>
#include <paludis/elike_package_dep_spec.hh>
#include <paludis/dep_spec.hh>
#include <paludis/environment.hh>
#include <paludis/repository.hh>
#include <paludis/package_id.hh>
#include <paludis/user_dep_spec.hh>
#include <list>
using namespace paludis;
using namespace paludis::fakerepository;
FakeDepParseError::FakeDepParseError(const std::string & s, const std::string & t) noexcept :
Exception("Error parsing '" + s + "': " + t)
{
}
namespace
{
template <typename T_>
struct ParseStackTypes
{
typedef std::list<std::shared_ptr<typename T_::BasicInnerNode> > Stack;
};
template <typename T_>
void package_dep_spec_string_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
{
PackageDepSpec p(parse_elike_package_dep_spec(s, ELikePackageDepSpecOptions() + epdso_allow_slot_deps
+ epdso_allow_slot_star_deps + epdso_allow_slot_equal_deps + epdso_allow_repository_deps
+ epdso_allow_use_deps + epdso_allow_ranged_deps + epdso_allow_tilde_greater_deps
+ epdso_allow_slot_equal_deps_portage + epdso_allow_subslot_deps
+ epdso_strict_parsing,
user_version_spec_options()));
(*h.begin())->append(std::make_shared<PackageDepSpec>(p));
}
template <typename T_>
void package_or_block_dep_spec_string_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
{
if ((! s.empty()) && ('!' == s.at(0)))
{
(*h.begin())->append(std::make_shared<BlockDepSpec>(s,
parse_elike_package_dep_spec(s.substr(1),
ELikePackageDepSpecOptions() + epdso_allow_slot_deps
+ epdso_allow_slot_star_deps + epdso_allow_slot_equal_deps + epdso_allow_repository_deps
+ epdso_allow_use_deps + epdso_allow_ranged_deps + epdso_allow_tilde_greater_deps
+ epdso_allow_slot_equal_deps_portage + epdso_allow_subslot_deps
+ epdso_strict_parsing,
user_version_spec_options())));
}
else
package_dep_spec_string_handler<T_>(h, s);
}
template <typename T_>
void license_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
{
(*h.begin())->append(std::make_shared<LicenseDepSpec>(s));
}
template <typename T_>
void simple_uri_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
{
(*h.begin())->append(std::make_shared<SimpleURIDepSpec>(s));
}
template <typename T_>
void arrow_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s, const std::string & t)
{
(*h.begin())->append(std::make_shared<FetchableURIDepSpec>(t.empty() ? s : s + " -> " + t));
}
void any_not_allowed_handler(const std::string & s) PALUDIS_ATTRIBUTE((noreturn));
void any_not_allowed_handler(const std::string & s)
{
throw FakeDepParseError(s, "Any dep specs not allowed here");
}
void exactly_one_not_allowed_handler(const std::string & s) PALUDIS_ATTRIBUTE((noreturn));
void exactly_one_not_allowed_handler(const std::string & s)
{
throw FakeDepParseError(s, "Exactly one dep specs not allowed here");
}
void at_most_one_not_allowed_handler(const std::string & s) PALUDIS_ATTRIBUTE((noreturn));
void at_most_one_not_allowed_handler(const std::string & s)
{
throw FakeDepParseError(s, "At most one dep specs not allowed here");
}
void arrows_not_allowed_handler(const std::string & s, const std::string & f, const std::string & t) PALUDIS_ATTRIBUTE((noreturn));
void arrows_not_allowed_handler(const std::string & s, const std::string & f, const std::string & t)
{
throw FakeDepParseError(s, "Arrow '" + f + " -> " + t + "' not allowed here");
}
void error_handler(const std::string & s, const std::string & t) PALUDIS_ATTRIBUTE((noreturn));
void error_handler(const std::string & s, const std::string & t)
{
throw FakeDepParseError(s, t);
}
void labels_not_allowed_handler(const std::string & s, const std::string & f) PALUDIS_ATTRIBUTE((noreturn));
void labels_not_allowed_handler(const std::string & s, const std::string & f)
{
throw FakeDepParseError(s, "Label '" + f + "' not allowed here");
}
template <typename T_, typename A_>
void any_all_handler(typename ParseStackTypes<T_>::Stack & stack)
{
stack.push_front((*stack.begin())->append(std::make_shared<A_>()));
}
template <typename T_>
void use_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & u)
{
stack.push_front((*stack.begin())->append(
std::make_shared<ConditionalDepSpec>(parse_elike_conditional_dep_spec(u, false))));
}
template <typename T_>
void pop_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & s)
{
stack.pop_front();
if (stack.empty())
throw FakeDepParseError(s, "Too many ')'s");
}
template <typename T_>
void should_be_empty_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & s)
{
if (1 != stack.size())
throw FakeDepParseError(s, "Nesting error");
}
void do_nothing()
{
}
void discard_annotations(const std::shared_ptr<const Map<std::string, std::string> > &)
{
}
}
std::shared_ptr<DependencySpecTree>
paludis::fakerepository::parse_depend(const std::string & s, const Environment * const)
{
using namespace std::placeholders;
ParseStackTypes<DependencySpecTree>::Stack stack;
std::shared_ptr<DependencySpecTree> top(std::make_shared<DependencySpecTree>(std::make_shared<AllDepSpec>()));
stack.push_front(top->top());
ELikeDepParserCallbacks callbacks(
make_named_values<ELikeDepParserCallbacks>(
n::on_all() = std::bind(&any_all_handler<DependencySpecTree, AllDepSpec>, std::ref(stack)),
n::on_annotations() = &discard_annotations,
n::on_any() = std::bind(&any_all_handler<DependencySpecTree, AnyDepSpec>, std::ref(stack)),
n::on_arrow() = std::bind(&arrows_not_allowed_handler, s, _1, _2),
n::on_at_most_one() = std::bind(&at_most_one_not_allowed_handler, s),
n::on_error() = std::bind(&error_handler, s, _1),
n::on_exactly_one() = std::bind(&exactly_one_not_allowed_handler, s),
n::on_label() = std::bind(&labels_not_allowed_handler, s, _1),
n::on_no_annotations() = &do_nothing,
n::on_pop() = std::bind(&pop_handler<DependencySpecTree>, std::ref(stack), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<DependencySpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&package_or_block_dep_spec_string_handler<DependencySpecTree>, std::ref(stack), _1),
n::on_use() = std::bind(&use_handler<DependencySpecTree>, std::ref(stack), _1),
n::on_use_under_any() = &do_nothing
));
parse_elike_dependencies(s, callbacks, { });
return top;
}
std::shared_ptr<FetchableURISpecTree>
paludis::fakerepository::parse_fetchable_uri(const std::string & s, const Environment * const)
{
using namespace std::placeholders;
ParseStackTypes<FetchableURISpecTree>::Stack stack;
std::shared_ptr<FetchableURISpecTree> top(std::make_shared<FetchableURISpecTree>(std::make_shared<AllDepSpec>()));
stack.push_front(top->top());
ELikeDepParserCallbacks callbacks(
make_named_values<ELikeDepParserCallbacks>(
n::on_all() = std::bind(&any_all_handler<FetchableURISpecTree, AllDepSpec>, std::ref(stack)),
n::on_annotations() = &discard_annotations,
n::on_any() = std::bind(&any_not_allowed_handler, s),
n::on_arrow() = std::bind(&arrow_handler<FetchableURISpecTree>, std::ref(stack), _1, _2),
n::on_at_most_one() = std::bind(&at_most_one_not_allowed_handler, s),
n::on_error() = std::bind(&error_handler, s, _1),
n::on_exactly_one() = std::bind(&exactly_one_not_allowed_handler, s),
n::on_label() = std::bind(&labels_not_allowed_handler, s, _1),
n::on_no_annotations() = &do_nothing,
n::on_pop() = std::bind(&pop_handler<FetchableURISpecTree>, std::ref(stack), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<FetchableURISpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&arrow_handler<FetchableURISpecTree>, std::ref(stack), _1, ""),
n::on_use() = std::bind(&use_handler<FetchableURISpecTree>, std::ref(stack), _1),
n::on_use_under_any() = &do_nothing
));
parse_elike_dependencies(s, callbacks, { });
return top;
}
std::shared_ptr<SimpleURISpecTree>
paludis::fakerepository::parse_simple_uri(const std::string & s, const Environment * const)
{
using namespace std::placeholders;
ParseStackTypes<SimpleURISpecTree>::Stack stack;
std::shared_ptr<SimpleURISpecTree> top(std::make_shared<SimpleURISpecTree>(std::make_shared<AllDepSpec>()));
stack.push_front(top->top());
ELikeDepParserCallbacks callbacks(
make_named_values<ELikeDepParserCallbacks>(
n::on_all() = std::bind(&any_all_handler<SimpleURISpecTree, AllDepSpec>, std::ref(stack)),
n::on_annotations() = &discard_annotations,
n::on_any() = std::bind(&any_not_allowed_handler, s),
n::on_arrow() = std::bind(&arrows_not_allowed_handler, s, _1, _2),
n::on_at_most_one() = std::bind(&at_most_one_not_allowed_handler, s),
n::on_error() = std::bind(&error_handler, s, _1),
n::on_exactly_one() = std::bind(&exactly_one_not_allowed_handler, s),
n::on_label() = std::bind(&labels_not_allowed_handler, s, _1),
n::on_no_annotations() = &do_nothing,
n::on_pop() = std::bind(&pop_handler<SimpleURISpecTree>, std::ref(stack), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<SimpleURISpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&simple_uri_handler<SimpleURISpecTree>, std::ref(stack), _1),
n::on_use() = std::bind(&use_handler<SimpleURISpecTree>, std::ref(stack), _1),
n::on_use_under_any() = &do_nothing
));
parse_elike_dependencies(s, callbacks, { });
return top;
}
std::shared_ptr<LicenseSpecTree>
paludis::fakerepository::parse_license(const std::string & s, const Environment * const)
{
using namespace std::placeholders;
ParseStackTypes<LicenseSpecTree>::Stack stack;
std::shared_ptr<LicenseSpecTree> top(std::make_shared<LicenseSpecTree>(std::make_shared<AllDepSpec>()));
stack.push_front(top->top());
ELikeDepParserCallbacks callbacks(
make_named_values<ELikeDepParserCallbacks>(
n::on_all() = std::bind(&any_all_handler<LicenseSpecTree, AllDepSpec>, std::ref(stack)),
n::on_annotations() = &discard_annotations,
n::on_any() = std::bind(&any_all_handler<LicenseSpecTree, AnyDepSpec>, std::ref(stack)),
n::on_arrow() = std::bind(&arrows_not_allowed_handler, s, _1, _2),
n::on_at_most_one() = std::bind(&at_most_one_not_allowed_handler, s),
n::on_error() = std::bind(&error_handler, s, _1),
n::on_exactly_one() = std::bind(&exactly_one_not_allowed_handler, s),
n::on_label() = std::bind(&labels_not_allowed_handler, s, _1),
n::on_no_annotations() = &do_nothing,
n::on_pop() = std::bind(&pop_handler<LicenseSpecTree>, std::ref(stack), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<LicenseSpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&license_handler<LicenseSpecTree>, std::ref(stack), _1),
n::on_use() = std::bind(&use_handler<LicenseSpecTree>, std::ref(stack), _1),
n::on_use_under_any() = &do_nothing
));
parse_elike_dependencies(s, callbacks, { });
return top;
}