Exheredludis/paludis/elike_choices.cc
2013-06-04 07:40:47 +01:00

953 lines
23 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/elike_choices.hh>
#include <paludis/environment.hh>
#include <paludis/permitted_choice_value_parameter_values.hh>
#include <paludis/util/tribool.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/destringify.hh>
#include <paludis/util/log.hh>
#include <paludis/util/singleton-impl.hh>
#include <paludis/util/enum_iterator.hh>
#include <paludis/util/map.hh>
#include <set>
#include <limits>
#include <istream>
#include <ostream>
using namespace paludis;
#include <paludis/elike_choices-se.cc>
namespace
{
struct CommonValues :
Singleton<CommonValues>
{
const std::shared_ptr<const PermittedChoiceValueParameterIntegerValue> permitted_jobs_values;
const std::shared_ptr<Map<std::string, std::string> > permitted_symbols;
const std::shared_ptr<const PermittedChoiceValueParameterEnumValue> permitted_symbols_values;
const std::shared_ptr<Map<std::string, std::string> > permitted_work;
const std::shared_ptr<const PermittedChoiceValueParameterEnumValue> permitted_work_values;
CommonValues() :
permitted_jobs_values(std::make_shared<PermittedChoiceValueParameterIntegerValue>(1, std::numeric_limits<int>::max())),
permitted_symbols(std::make_shared<Map<std::string, std::string> >()),
permitted_symbols_values(std::make_shared<PermittedChoiceValueParameterEnumValue>(permitted_symbols)),
permitted_work(std::make_shared<Map<std::string, std::string> >()),
permitted_work_values(std::make_shared<PermittedChoiceValueParameterEnumValue>(permitted_work))
{
for (EnumIterator<ELikeSymbolsChoiceValueParameter> e, e_end(last_escvp) ;
e != e_end ; ++e)
{
switch (*e)
{
case escvp_split:
permitted_symbols->insert("split", "Split debug symbols");
continue;
case escvp_preserve:
permitted_symbols->insert("preserve", "Preserve debug symbols");
continue;
case escvp_strip:
permitted_symbols->insert("strip", "Strip debug symbols");
continue;
case escvp_compress:
permitted_symbols->insert("compress", "Split and compress debug symbols");
continue;
case last_escvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeSymbolsChoiceValueParameter");
}
for (EnumIterator<ELikeWorkChoiceValueParameter> e, e_end(last_ewcvp) ;
e != e_end ; ++e)
{
switch (*e)
{
case ewcvp_tidyup:
permitted_work->insert("tidyup", "Tidy up work directory after a successful build");
continue;
case ewcvp_preserve:
permitted_work->insert("preserve", "Preserve the working directory");
continue;
case ewcvp_remove:
permitted_work->insert("remove", "Always remove the working directory");
continue;
case ewcvp_leave:
permitted_work->insert("leave", "Do not remove, but allow destructive merges");
continue;
case last_ewcvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeWorkChoiceValueParameter");
}
}
};
}
const UnprefixedChoiceName
ELikeOptionalTestsChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("optional_tests");
}
const ChoiceNameWithPrefix
ELikeOptionalTestsChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix()) + ":" + stringify(canonical_unprefixed_name()));
}
ELikeOptionalTestsChoiceValue::ELikeOptionalTestsChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env, const std::shared_ptr<const Choice> & choice,
const bool l) :
_enabled((! l) && (env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_true())),
_mask(l)
{
}
const UnprefixedChoiceName
ELikeOptionalTestsChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeOptionalTestsChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeOptionalTestsChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeOptionalTestsChoiceValue::enabled_by_default() const
{
return false;
}
bool
ELikeOptionalTestsChoiceValue::locked() const
{
return _mask;
}
const std::string
ELikeOptionalTestsChoiceValue::description() const
{
return "Run tests considered by the package to be optional";
}
ChoiceOrigin
ELikeOptionalTestsChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeOptionalTestsChoiceValue::parameter() const
{
return "";
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeOptionalTestsChoiceValue::permitted_parameter_values() const
{
return nullptr;
}
bool
ELikeOptionalTestsChoiceValue::presumed() const
{
return false;
}
const UnprefixedChoiceName
ELikeRecommendedTestsChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("recommended_tests");
}
const ChoiceNameWithPrefix
ELikeRecommendedTestsChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix()) + ":" + stringify(canonical_unprefixed_name()));
}
ELikeRecommendedTestsChoiceValue::ELikeRecommendedTestsChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env, const std::shared_ptr<const Choice> & choice,
const bool l) :
_enabled((! l) && (! env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_false())),
_mask(l)
{
}
const UnprefixedChoiceName
ELikeRecommendedTestsChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeRecommendedTestsChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeRecommendedTestsChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeRecommendedTestsChoiceValue::enabled_by_default() const
{
return true;
}
bool
ELikeRecommendedTestsChoiceValue::locked() const
{
return _mask;
}
const std::string
ELikeRecommendedTestsChoiceValue::description() const
{
return "Run tests considered by the package to be recommended";
}
ChoiceOrigin
ELikeRecommendedTestsChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeRecommendedTestsChoiceValue::parameter() const
{
return "";
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeRecommendedTestsChoiceValue::permitted_parameter_values() const
{
return nullptr;
}
bool
ELikeRecommendedTestsChoiceValue::presumed() const
{
return false;
}
const ChoicePrefixName
paludis::canonical_build_options_prefix()
{
return ChoicePrefixName("build_options");
}
const std::string
paludis::canonical_build_options_raw_name()
{
return "build_options";
}
const std::string
paludis::canonical_build_options_human_name()
{
return "Build Options";
}
const UnprefixedChoiceName
ELikeExpensiveTestsChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("expensive_tests");
}
const ChoiceNameWithPrefix
ELikeExpensiveTestsChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix()) + ":" + stringify(canonical_unprefixed_name()));
}
ELikeExpensiveTestsChoiceValue::ELikeExpensiveTestsChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env, const std::shared_ptr<const Choice> & choice,
const bool l) :
_enabled((! l) && (env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_true())),
_mask(l)
{
}
const UnprefixedChoiceName
ELikeExpensiveTestsChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeExpensiveTestsChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeExpensiveTestsChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeExpensiveTestsChoiceValue::enabled_by_default() const
{
return false;
}
bool
ELikeExpensiveTestsChoiceValue::locked() const
{
return _mask;
}
const std::string
ELikeExpensiveTestsChoiceValue::description() const
{
return "Run tests considered by the package to be useful, but expensive";
}
ChoiceOrigin
ELikeExpensiveTestsChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeExpensiveTestsChoiceValue::parameter() const
{
return "";
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeExpensiveTestsChoiceValue::permitted_parameter_values() const
{
return nullptr;
}
bool
ELikeExpensiveTestsChoiceValue::presumed() const
{
return false;
}
const UnprefixedChoiceName
ELikeJobsChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("jobs");
}
const ChoiceNameWithPrefix
ELikeJobsChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix()) + ":" + stringify(canonical_unprefixed_name()));
}
namespace
{
std::string get_jobs(const std::shared_ptr<const PackageID> & id,
const std::string & env_value)
{
if (env_value.empty())
return "1";
try
{
return stringify(destringify<unsigned>(env_value));
}
catch (const DestringifyError &)
{
Context context("When getting value of the jobs option for '" + stringify(*id) + "':");
Log::get_instance()->message("elike_jobs_choice_value.invalid", ll_warning, lc_context)
<< "Value '" << env_value << "' is not an unsigned integer, using \"1\" instead";
return "1";
}
}
}
ELikeJobsChoiceValue::ELikeJobsChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env, const std::shared_ptr<const Choice> & choice) :
_enabled(env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_true()),
_parameter(get_jobs(id, env->value_for_choice_parameter(id, choice, canonical_unprefixed_name())))
{
}
const UnprefixedChoiceName
ELikeJobsChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeJobsChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeJobsChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeJobsChoiceValue::enabled_by_default() const
{
return false;
}
bool
ELikeJobsChoiceValue::locked() const
{
return false;
}
const std::string
ELikeJobsChoiceValue::description() const
{
return "How many jobs the package's build system should use, where supported";
}
ChoiceOrigin
ELikeJobsChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeJobsChoiceValue::parameter() const
{
return _parameter;
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeJobsChoiceValue::permitted_parameter_values() const
{
return CommonValues::get_instance()->permitted_jobs_values;
}
bool
ELikeJobsChoiceValue::presumed() const
{
return false;
}
const UnprefixedChoiceName
ELikeTraceChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("trace");
}
const ChoiceNameWithPrefix
ELikeTraceChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix()) + ":" +
stringify(canonical_unprefixed_name()));
}
ELikeTraceChoiceValue::ELikeTraceChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env, const std::shared_ptr<const Choice> & choice) :
_enabled(env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_true())
{
}
const UnprefixedChoiceName
ELikeTraceChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeTraceChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeTraceChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeTraceChoiceValue::enabled_by_default() const
{
return false;
}
bool
ELikeTraceChoiceValue::locked() const
{
return false;
}
const std::string
ELikeTraceChoiceValue::description() const
{
return "Trace actions executed by the package (very noisy, for debugging broken builds only)";
}
ChoiceOrigin
ELikeTraceChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeTraceChoiceValue::parameter() const
{
return "";
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeTraceChoiceValue::permitted_parameter_values() const
{
return nullptr;
}
bool
ELikeTraceChoiceValue::presumed() const
{
return false;
}
namespace
{
ELikeSymbolsChoiceValueParameter get_symbols(const std::shared_ptr<const PackageID> & id,
const std::string & env_value)
{
if (env_value.empty())
return escvp_split;
try
{
return destringify<ELikeSymbolsChoiceValueParameter>(env_value);
}
catch (const DestringifyError &)
{
Context context("When getting value of the symbols option for '" + stringify(*id) + "':");
Log::get_instance()->message("elike_symbols_choice_value.invalid", ll_warning, lc_context)
<< "Value '" << env_value << "' is not a legal value, using \"split\" instead";
return escvp_split;
}
}
}
ELikeSymbolsChoiceValue::ELikeSymbolsChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env, const std::shared_ptr<const Choice> & choice, const ELikeSymbolsChoiceValueParameter _force) :
_enabled(! env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_false()),
_param(_force != last_escvp ? _force : get_symbols(id, env->value_for_choice_parameter(id, choice, canonical_unprefixed_name())))
{
}
const UnprefixedChoiceName
ELikeSymbolsChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeSymbolsChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeSymbolsChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeSymbolsChoiceValue::enabled_by_default() const
{
return true;
}
bool
ELikeSymbolsChoiceValue::locked() const
{
return false;
}
const std::string
ELikeSymbolsChoiceValue::description() const
{
return "How to handle debug symbols in installed files";
}
ChoiceOrigin
ELikeSymbolsChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeSymbolsChoiceValue::parameter() const
{
return stringify(_param);
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeSymbolsChoiceValue::permitted_parameter_values() const
{
return CommonValues::get_instance()->permitted_symbols_values;
}
bool
ELikeSymbolsChoiceValue::presumed() const
{
return false;
}
const UnprefixedChoiceName
ELikeSymbolsChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("symbols");
}
const ChoiceNameWithPrefix
ELikeSymbolsChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix()) + ":" + stringify(canonical_unprefixed_name()));
}
bool
ELikeSymbolsChoiceValue::should_split(const std::string & v)
{
switch (destringify<ELikeSymbolsChoiceValueParameter>(v))
{
case escvp_split:
case escvp_compress:
return true;
case escvp_preserve:
case escvp_strip:
return false;
case last_escvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeSymbolsChoiceValueParameter");
}
bool
ELikeSymbolsChoiceValue::should_strip(const std::string & v)
{
switch (destringify<ELikeSymbolsChoiceValueParameter>(v))
{
case escvp_split:
case escvp_compress:
case escvp_strip:
return true;
case escvp_preserve:
return false;
case last_escvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeSymbolsChoiceValueParameter");
}
bool
ELikeSymbolsChoiceValue::should_compress(const std::string & v)
{
switch (destringify<ELikeSymbolsChoiceValueParameter>(v))
{
case escvp_compress:
return true;
case escvp_split:
case escvp_preserve:
case escvp_strip:
return false;
case last_escvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeSymbolsChoiceValueParameter");
}
namespace
{
ELikeWorkChoiceValueParameter get_work(const std::shared_ptr<const PackageID> & id,
const std::string & env_value)
{
if (env_value.empty())
return ewcvp_tidyup;
try
{
return destringify<ELikeWorkChoiceValueParameter>(env_value);
}
catch (const DestringifyError &)
{
Context context("When getting value of the symbols option for '" + stringify(*id) + "':");
Log::get_instance()->message("elike_work_choice_value.invalid", ll_warning, lc_context)
<< "Value '" << env_value << "' is not a legal value, using \"tidyup\" instead";
return ewcvp_tidyup;
}
}
}
ELikeWorkChoiceValue::ELikeWorkChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env, const std::shared_ptr<const Choice> & choice, const ELikeWorkChoiceValueParameter _force) :
_enabled(! env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_false()),
_param(_force != last_ewcvp ? _force : get_work(id, env->value_for_choice_parameter(id, choice, canonical_unprefixed_name())))
{
}
const UnprefixedChoiceName
ELikeWorkChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeWorkChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeWorkChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeWorkChoiceValue::enabled_by_default() const
{
return true;
}
bool
ELikeWorkChoiceValue::locked() const
{
return false;
}
const std::string
ELikeWorkChoiceValue::description() const
{
return "Whether to preserve or remove working directories";
}
ChoiceOrigin
ELikeWorkChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeWorkChoiceValue::parameter() const
{
return stringify(_param);
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeWorkChoiceValue::permitted_parameter_values() const
{
return CommonValues::get_instance()->permitted_work_values;
}
bool
ELikeWorkChoiceValue::presumed() const
{
return false;
}
const UnprefixedChoiceName
ELikeWorkChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("work");
}
const ChoiceNameWithPrefix
ELikeWorkChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix()) + ":" + stringify(canonical_unprefixed_name()));
}
bool
ELikeWorkChoiceValue::should_remove(const std::string & v)
{
switch (destringify<ELikeWorkChoiceValueParameter>(v))
{
case ewcvp_tidyup:
case ewcvp_remove:
return true;
case ewcvp_preserve:
case ewcvp_leave:
return false;
case last_ewcvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeWorkChoiceValueParameter");
}
bool
ELikeWorkChoiceValue::should_merge_nondestructively(const std::string & v)
{
switch (destringify<ELikeWorkChoiceValueParameter>(v))
{
case ewcvp_preserve:
return true;
case ewcvp_tidyup:
case ewcvp_remove:
case ewcvp_leave:
return false;
case last_ewcvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeWorkChoiceValueParameter");
}
bool
ELikeWorkChoiceValue::should_remove_on_failure(const std::string & v)
{
switch (destringify<ELikeWorkChoiceValueParameter>(v))
{
case ewcvp_remove:
return true;
case ewcvp_tidyup:
case ewcvp_preserve:
case ewcvp_leave:
return false;
case last_ewcvp:
break;
}
throw InternalError(PALUDIS_HERE, "Unhandled ELikeWorkChoiceValueParameter");
}
// ELikeDwarfCompressionChoiceValue
const UnprefixedChoiceName
ELikeDwarfCompressionChoiceValue::canonical_unprefixed_name()
{
return UnprefixedChoiceName("dwarf_compress");
}
const ChoiceNameWithPrefix
ELikeDwarfCompressionChoiceValue::canonical_name_with_prefix()
{
return ChoiceNameWithPrefix(stringify(canonical_build_options_prefix())
+ ":" +
stringify(canonical_unprefixed_name()));
}
ELikeDwarfCompressionChoiceValue::ELikeDwarfCompressionChoiceValue(const std::shared_ptr<const PackageID> & id,
const Environment * const env,
const std::shared_ptr<const Choice> & choice)
: _enabled(env->want_choice_enabled(id, choice, canonical_unprefixed_name()).is_true())
{
}
const UnprefixedChoiceName
ELikeDwarfCompressionChoiceValue::unprefixed_name() const
{
return canonical_unprefixed_name();
}
const ChoiceNameWithPrefix
ELikeDwarfCompressionChoiceValue::name_with_prefix() const
{
return canonical_name_with_prefix();
}
bool
ELikeDwarfCompressionChoiceValue::enabled() const
{
return _enabled;
}
bool
ELikeDwarfCompressionChoiceValue::enabled_by_default() const
{
return false;
}
bool
ELikeDwarfCompressionChoiceValue::presumed() const
{
return false;
}
bool
ELikeDwarfCompressionChoiceValue::locked() const
{
return false;
}
const std::string
ELikeDwarfCompressionChoiceValue::description() const
{
return "Compress DWARF2+ debug information";
}
ChoiceOrigin
ELikeDwarfCompressionChoiceValue::origin() const
{
return co_special;
}
const std::string
ELikeDwarfCompressionChoiceValue::parameter() const
{
return "";
}
const std::shared_ptr<const PermittedChoiceValueParameterValues>
ELikeDwarfCompressionChoiceValue::permitted_parameter_values() const
{
return nullptr;
}