aboutsummaryrefslogtreecommitdiff
path: root/paludis/repositories/e/ebuild_id.cc
diff options
context:
space:
mode:
Diffstat (limited to 'paludis/repositories/e/ebuild_id.cc')
-rw-r--r--paludis/repositories/e/ebuild_id.cc77
1 files changed, 74 insertions, 3 deletions
diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc
index ae6ae9773..f2dc1ad92 100644
--- a/paludis/repositories/e/ebuild_id.cc
+++ b/paludis/repositories/e/ebuild_id.cc
@@ -69,6 +69,7 @@
#include <paludis/util/fs_stat.hh>
#include <paludis/util/join.hh>
#include <paludis/util/upper_lower.hh>
+#include <paludis/util/safe_ifstream.hh>
#include <set>
#include <iterator>
@@ -140,6 +141,7 @@ namespace paludis
const RepositoryName repository_name;
mutable std::shared_ptr<const EAPI> eapi;
const std::string guessed_eapi;
+ const bool eapi_from_suffix;
const time_t master_mtime;
const std::shared_ptr<const EclassMtimes> eclass_mtimes;
mutable bool has_non_xml_keys;
@@ -187,12 +189,13 @@ namespace paludis
Imp(const QualifiedPackageName & q, const VersionSpec & v,
const Environment * const e,
const RepositoryName & r, const FSPath & f, const std::string & g,
- const time_t t, const std::shared_ptr<const EclassMtimes> & m) :
+ const bool es, const time_t t, const std::shared_ptr<const EclassMtimes> & m) :
name(q),
version(v),
environment(e),
repository_name(r),
guessed_eapi(g),
+ eapi_from_suffix(es),
master_mtime(t),
eclass_mtimes(m),
has_non_xml_keys(false),
@@ -209,9 +212,10 @@ EbuildID::EbuildID(const QualifiedPackageName & q, const VersionSpec & v,
const RepositoryName & r,
const FSPath & f,
const std::string & g,
+ const bool es,
const time_t t,
const std::shared_ptr<const EclassMtimes> & m) :
- _imp(q, v, e, r, f, g, t, m)
+ _imp(q, v, e, r, f, g, es, t, m)
{
}
@@ -281,7 +285,7 @@ EbuildID::need_non_xml_keys_added() const
_imp->environment->trigger_notifier_callback(NotifierCallbackGeneratingMetadataEvent(repository_name()));
- _imp->eapi = EAPIData::get_instance()->eapi_from_string(_imp->guessed_eapi);
+ _imp->eapi = presource_eapi();
if (_imp->eapi->supported())
{
@@ -420,6 +424,73 @@ EbuildID::need_non_xml_keys_added() const
add_metadata_key(_imp->choices);
}
+const std::shared_ptr<const EAPI>
+EbuildID::presource_eapi() const
+{
+ auto guessed(EAPIData::get_instance()->eapi_from_string(_imp->guessed_eapi));
+ if (_imp->eapi_from_suffix || ! guessed->supported())
+ return guessed;
+
+ Context ctx("When parsing EAPI from '" + stringify(_imp->fs_location->parse_value()) + "':");
+
+ std::string eapi_assign(guessed->supported()->ebuild_metadata_variables()->eapi()->name());
+ eapi_assign += '=';
+
+ try
+ {
+ SafeIFStream eb(_imp->fs_location->parse_value());
+ std::string line;
+
+ while (std::getline(eb, line))
+ {
+ std::string::size_type past_indent(line.find_first_not_of(" \t"));
+ if (std::string::npos == past_indent || line.at(past_indent) == '#')
+ continue;
+
+ if (line.compare(past_indent, eapi_assign.length(), eapi_assign) != 0)
+ break;
+ std::string::size_type value_start(past_indent + eapi_assign.length());
+
+ char quote('\0');
+ if (line.length() > value_start && (line.at(value_start) == '"' || line.at(value_start) == '\''))
+ {
+ quote = line.at(value_start++);
+ if (line.length() < value_start)
+ break;
+ }
+
+ std::string::size_type value_end(line.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_.-", value_start));
+ std::string value(line, value_start, std::string::npos == value_end
+ ? std::string::npos : value_end - value_start);
+
+ if ('\0' != quote && (std::string::npos == value_end || line.at(value_end++) != quote))
+ break;
+
+ if (std::string::npos != value_end)
+ {
+ std::string::size_type trailing(line.find_first_not_of(" \t", value_end));
+ if (std::string::npos != trailing && (trailing == value_end || '#' != line.at(trailing)))
+ break;
+ }
+
+ if (value.empty())
+ {
+ auto repo(_imp->environment->fetch_repository(repository_name()));
+ auto e_repo(std::static_pointer_cast<const ERepository>(repo));
+ return EAPIData::get_instance()->eapi_from_string(e_repo->params().eapi_when_unspecified());
+ }
+ return EAPIData::get_instance()->eapi_from_string(value);
+ }
+ }
+ catch (const SafeIFStreamError & e)
+ {
+ Log::get_instance()->message("e.ebuild.metadata.eapi_unparsable", ll_warning, lc_context) << e.message();
+ return EAPIData::get_instance()->unknown_eapi();
+ }
+
+ return guessed;
+}
+
void
EbuildID::need_xml_keys_added() const
{