aboutsummaryrefslogtreecommitdiff
path: root/libbpkg
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-12-07 21:38:00 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-12-11 13:59:03 +0300
commitfbabb3ddf7f9bee71a6be767cc911b5b3b96333a (patch)
treeaa3b31024f2fb0c6b53961afbfe9de2a6ba29cb8 /libbpkg
parentb05ca3928c826b46a087f3e1f8ff24069c65ff0b (diff)
Add support for build configuration class inheritance
Diffstat (limited to 'libbpkg')
-rw-r--r--libbpkg/manifest.cxx43
-rw-r--r--libbpkg/manifest.hxx27
2 files changed, 56 insertions, 14 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index 73d2311..8782409 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -1179,6 +1179,7 @@ namespace bpkg
//
static void
match_classes (const strings& cs,
+ const build_class_inheritance_map& im,
const vector<build_class_term>& expr,
bool& r)
{
@@ -1191,18 +1192,44 @@ namespace bpkg
if ((t.operation == '+') == r)
continue;
- bool m;
+ bool m (false);
// We don't expect the class list to be long, so the linear search should
// be fine.
//
if (t.simple)
- m = find (cs.begin (), cs.end (), t.name) != cs.end ();
- else
{
- m = false;
- match_classes (cs, t.expr, m);
+ // Check if any of the classes or their bases match the term name.
+ //
+ for (const string& c: cs)
+ {
+ m = (c == t.name);
+
+ if (!m)
+ {
+ // Go through base classes.
+ //
+ for (auto i (im.find (c)); i != im.end (); )
+ {
+ const string& base (i->second);
+
+ // Bail out if the base class matches.
+ //
+ m = (base == t.name);
+
+ if (m)
+ break;
+
+ i = im.find (base);
+ }
+ }
+
+ if (m)
+ break;
+ }
}
+ else
+ match_classes (cs, im, t.expr, m);
if (t.inverted)
m = !m;
@@ -1218,9 +1245,11 @@ namespace bpkg
}
void build_class_expr::
- match (const strings& cs, bool& r) const
+ match (const strings& cs,
+ const build_class_inheritance_map& im,
+ bool& r) const
{
- match_classes (cs, expr, r);
+ match_classes (cs, im, expr, r);
}
// pkg_package_manifest
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index 55e9d15..fc61511 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -5,6 +5,7 @@
#ifndef LIBBPKG_MANIFEST_HXX
#define LIBBPKG_MANIFEST_HXX
+#include <map>
#include <string>
#include <vector>
#include <cassert>
@@ -476,6 +477,10 @@ namespace bpkg
validate_name (const std::string&);
};
+ // Map of derived build classes to their bases.
+ //
+ using build_class_inheritance_map = std::map<std::string, std::string>;
+
// Build configuration class expression. Includes comment and optional
// underlying set.
//
@@ -527,20 +532,28 @@ namespace bpkg
string () const;
// Match a build configuration that belongs to the specified list of
- // classes against the expression. Either return or update the result (the
- // latter allows to sequentially matching against a list of expressions).
+ // classes (and recursively to their bases) against the expression. Either
+ // return or update the result (the latter allows to sequentially matching
+ // against a list of expressions).
+ //
+ // Notes:
+ //
+ // - The derived-to-base map is not verified (that there are no
+ // inheritance cycles, etc.).
//
- // Note: the underlying class set doesn't affect the match in any way (it
- // should have been used to pre-filter the set of build configurations).
+ // - The underlying class set doesn't affect the match in any way (it
+ // should have been used to pre-filter the set of build configurations).
//
void
- match (const strings&, bool& result) const;
+ match (const strings&,
+ const build_class_inheritance_map&,
+ bool& result) const;
bool
- match (const strings& cs) const
+ match (const strings& cs, const build_class_inheritance_map& bs) const
{
bool r (false);
- match (cs, r);
+ match (cs, bs, r);
return r;
}
};