Exheredludis/paludis/repositories/e/exheres_profile.cc
Saleem Abdulrasool 64ba7d5be8 modernize: use default method synthesis
Convert a number of destructors to default synthesized functions.  Try to
inline a few instances into the header.  It should be possible to inline all of
them, however, gcc seems to emit a number of warnings.  Furthermore, some of the
destructors are pure-virtualed, but provide an implementation.  Placing the
definition into the header causes ODR violations.
2016-08-06 11:58:04 -07:00

345 lines
12 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 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/e/exheres_profile.hh>
#include <paludis/repositories/e/e_repository_exceptions.hh>
#include <paludis/repositories/e/e_repository.hh>
#include <paludis/repositories/e/eapi.hh>
#include <paludis/repositories/e/dep_parser.hh>
#include <paludis/util/log.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/pimp-impl.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/wrapped_output_iterator.hh>
#include <paludis/util/config_file.hh>
#include <paludis/util/map.hh>
#include <paludis/util/set.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/hashes.hh>
#include <paludis/util/system.hh>
#include <paludis/util/fs_stat.hh>
#include <paludis/util/safe_ifstream.hh>
#include <paludis/choice.hh>
#include <paludis/environment.hh>
#include <paludis/match_package.hh>
#include <paludis/distribution.hh>
#include <paludis/package_id.hh>
#include <paludis/metadata_key.hh>
#include <paludis/paludislike_options_conf.hh>
#include <paludis/dep_spec_flattener.hh>
#include <unordered_map>
#include <list>
using namespace paludis;
using namespace paludis::erepository;
namespace
{
const std::shared_ptr<const LineConfigFile> make_config_file(
const FSPath & f,
const LineConfigFileOptions & o)
{
return std::make_shared<LineConfigFile>(f, o);
}
typedef std::unordered_map<std::string, std::string, Hash<std::string> > EnvironmentVariablesMap;
typedef std::unordered_map<QualifiedPackageName,
std::list<std::pair<std::shared_ptr<const PackageDepSpec>, std::shared_ptr<const MaskInfo> > >,
Hash<QualifiedPackageName> > PackageMaskMap;
}
namespace paludis
{
template<>
struct Imp<ExheresProfile>
{
const Environment * const env;
const bool has_master_repositories;
const EAPIForFileFunction eapi_for_file;
std::shared_ptr<FSPathSequence> profiles_with_parents;
PaludisLikeOptionsConf options_conf;
EnvironmentVariablesMap environment_variables;
const std::shared_ptr<Set<std::string> > use_expand;
const std::shared_ptr<Set<std::string> > use_expand_hidden;
const std::shared_ptr<Set<std::string>> use_expand_no_describe;
const std::shared_ptr<Set<std::string> > use_expand_unprefixed;
const std::shared_ptr<Set<std::string> > use_expand_implicit;
const std::shared_ptr<Set<std::string> > iuse_implicit;
const std::shared_ptr<Set<std::string> > use_expand_values;
const std::shared_ptr<SetSpecTree> system_packages;
Imp(
const Environment * const e,
const EAPIForFileFunction & f,
const bool h) :
env(e),
has_master_repositories(h),
eapi_for_file(f),
profiles_with_parents(std::make_shared<FSPathSequence>()),
options_conf(make_named_values<PaludisLikeOptionsConfParams>(
n::allow_locking() = true,
n::environment() = e,
n::make_config_file() = &make_config_file
)),
use_expand(std::make_shared<Set<std::string>>()),
use_expand_hidden(std::make_shared<Set<std::string>>()),
use_expand_no_describe(std::make_shared<Set<std::string>>()),
use_expand_unprefixed(std::make_shared<Set<std::string>>()),
use_expand_implicit(std::make_shared<Set<std::string>>()),
iuse_implicit(std::make_shared<Set<std::string>>()),
use_expand_values(std::make_shared<Set<std::string>>()),
system_packages(std::make_shared<SetSpecTree>(std::make_shared<AllDepSpec>()))
{
environment_variables["CONFIG_PROTECT"] = getenv_with_default("CONFIG_PROTECT", "/etc");
environment_variables["CONFIG_PROTECT_MASK"] = getenv_with_default("CONFIG_PROTECT_MASK", "");
}
};
}
ExheresProfile::ExheresProfile(
const Environment * const env,
const RepositoryName &,
const EAPIForFileFunction & eapi_for_file,
const IsArchFlagFunction &,
const FSPathSequence & location,
const std::string &,
const bool,
const bool has_master_repositories,
const bool) :
_imp(env, eapi_for_file, has_master_repositories)
{
for (FSPathSequence::ConstIterator l(location.begin()), l_end(location.end()) ;
l != l_end ; ++l)
_load_dir(*l);
const std::shared_ptr<const Set<UnprefixedChoiceName> > s(_imp->options_conf.known_choice_value_names(
nullptr, ChoicePrefixName("suboptions")));
for (Set<UnprefixedChoiceName>::ConstIterator f(s->begin()), f_end(s->end()) ;
f != f_end ; ++f)
if (_imp->options_conf.want_choice_enabled_locked(nullptr,
ChoicePrefixName("suboptions"), *f).first.is_true())
_imp->use_expand->insert(stringify(*f));
const std::shared_ptr<const Set<UnprefixedChoiceName> > sh(_imp->options_conf.known_choice_value_names(
nullptr, ChoicePrefixName("hidden_suboptions")));
for (Set<UnprefixedChoiceName>::ConstIterator f(sh->begin()), f_end(sh->end()) ;
f != f_end ; ++f)
if (_imp->options_conf.want_choice_enabled_locked(nullptr,
ChoicePrefixName("hidden_suboptions"), *f).first.is_true())
_imp->use_expand_hidden->insert(stringify(*f));
const std::shared_ptr<const Set<UnprefixedChoiceName>> suboptions_no_describe =
_imp->options_conf.known_choice_value_names(nullptr,
ChoicePrefixName("suboptions_no_describe"));
for (const auto & suboption : *suboptions_no_describe)
_imp->use_expand_no_describe->insert(stringify(suboption));
}
ExheresProfile::~ExheresProfile() = default;
void
ExheresProfile::_load_dir(const FSPath & f)
{
if (! f.stat().is_directory_or_symlink_to_directory())
{
Log::get_instance()->message("e.exheres_profile.not_a_directory", ll_warning, lc_context) <<
"Profile component '" << f << "' is not a directory";
return;
}
if ((f / "parents.conf").stat().exists())
{
LineConfigFile file(f / "parents.conf", { });
for (LineConfigFile::ConstIterator line(file.begin()), line_end(file.end()) ;
line != line_end ; ++line)
_load_dir((f / *line).realpath());
}
if ((f / "options.conf").stat().exists())
_imp->options_conf.add_file(f / "options.conf");
if (! _imp->has_master_repositories)
{
if ((f / "system.conf").stat().exists())
{
SafeIFStream file(f / "system.conf");
std::string file_text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
auto eapi(EAPIData::get_instance()->eapi_from_string(_imp->eapi_for_file(f / "system.conf")));
auto specs(parse_commented_set(file_text, _imp->env, *EAPIData::get_instance()->eapi_from_string(_imp->eapi_for_file(f / "system.conf"))));
DepSpecFlattener<SetSpecTree, PackageDepSpec> flat_specs(_imp->env, nullptr);
specs->top()->accept(flat_specs);
for (auto s(flat_specs.begin()), s_end(flat_specs.end()) ;
s != s_end ; ++s)
_imp->system_packages->top()->append(std::make_shared<PackageDepSpec>(**s));
}
}
if ((f / "make.defaults").stat().exists())
{
auto eapi(EAPIData::get_instance()->eapi_from_string(_imp->eapi_for_file(f / "make.defaults")));
if (! eapi->supported())
throw ERepositoryConfigurationError("Can't use profile directory '" + stringify(f) +
"' because it uses an unsupported EAPI");
KeyValueConfigFile file(f / "make.defaults", { kvcfo_disallow_source, kvcfo_disallow_space_inside_unquoted_values,
kvcfo_allow_inline_comments, kvcfo_allow_multiple_assigns_per_line },
&KeyValueConfigFile::no_defaults, &KeyValueConfigFile::no_transformation);
for (KeyValueConfigFile::ConstIterator k(file.begin()), k_end(file.end()) ;
k != k_end ; ++k)
_imp->environment_variables[k->first] = k->second;
}
_imp->profiles_with_parents->push_back(f);
}
std::shared_ptr<const FSPathSequence>
ExheresProfile::profiles_with_parents() const
{
return _imp->profiles_with_parents;
}
bool
ExheresProfile::use_masked(
const std::shared_ptr<const EbuildID> & id,
const std::shared_ptr<const Choice> & choice,
const UnprefixedChoiceName & value_unprefixed,
const ChoiceNameWithPrefix &
) const
{
std::pair<Tribool, bool> enabled_locked(_imp->options_conf.want_choice_enabled_locked(
id, choice->prefix(), value_unprefixed));
return enabled_locked.first.is_false() && enabled_locked.second;
}
bool
ExheresProfile::use_forced(
const std::shared_ptr<const EbuildID> & id,
const std::shared_ptr<const Choice> & choice,
const UnprefixedChoiceName & value_unprefixed,
const ChoiceNameWithPrefix &
) const
{
std::pair<Tribool, bool> enabled_locked(_imp->options_conf.want_choice_enabled_locked(
id, choice->prefix(), value_unprefixed));
return enabled_locked.first.is_true() && enabled_locked.second;
}
Tribool
ExheresProfile::use_state_ignoring_masks(
const std::shared_ptr<const PackageID> & id,
const std::shared_ptr<const Choice> & choice,
const UnprefixedChoiceName & value_unprefixed,
const ChoiceNameWithPrefix &
) const
{
std::pair<Tribool, bool> enabled_locked(_imp->options_conf.want_choice_enabled_locked(
id, choice->prefix(), value_unprefixed));
return enabled_locked.first;
}
const std::shared_ptr<const Set<UnprefixedChoiceName> >
ExheresProfile::known_choice_value_names(
const std::shared_ptr<const erepository::ERepositoryID> & id,
const std::shared_ptr<const Choice> & choice
) const
{
return _imp->options_conf.known_choice_value_names(id, choice->prefix());
}
const std::shared_ptr<const Set<std::string> >
ExheresProfile::use_expand() const
{
return _imp->use_expand;
}
const std::shared_ptr<const Set<std::string> >
ExheresProfile::use_expand_hidden() const
{
return _imp->use_expand_hidden;
}
const std::shared_ptr<const Set<std::string>>
ExheresProfile::use_expand_no_describe() const
{
return _imp->use_expand_no_describe;
}
const std::shared_ptr<const Set<std::string> >
ExheresProfile::use_expand_unprefixed() const
{
return _imp->use_expand_unprefixed;
}
const std::shared_ptr<const Set<std::string> >
ExheresProfile::use_expand_implicit() const
{
return _imp->use_expand_implicit;
}
const std::shared_ptr<const Set<std::string> >
ExheresProfile::iuse_implicit() const
{
return _imp->iuse_implicit;
}
const std::shared_ptr<const Set<std::string> >
ExheresProfile::use_expand_values(const std::string &) const
{
return _imp->use_expand_values;
}
const std::string
ExheresProfile::environment_variable(const std::string & s) const
{
EnvironmentVariablesMap::const_iterator i(_imp->environment_variables.find(s));
if (_imp->environment_variables.end() == i)
{
Log::get_instance()->message("e.exheres_profile.unknown", ll_warning, lc_context) <<
"Something is asking for environment variable '" << s << "' from profiles, but that isn't in "
"our list of special vars. This is probably a bug.";
return "";
}
else
return i->second;
}
const std::shared_ptr<const MasksInfo>
ExheresProfile::profile_masks(const std::shared_ptr<const PackageID> &) const
{
auto result(std::make_shared<MasksInfo>());
return result;
}
const std::shared_ptr<const SetSpecTree>
ExheresProfile::system_packages() const
{
return _imp->system_packages;
}