aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-07-13 09:30:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-07-13 09:30:52 +0200
commit4b15244f65eb246d4e5d98ebfc1aa3137dc7275e (patch)
tree7bb1564772662ef22ea0dc12788938b28213b57c
parentdb73844a1e11787025a8642f69a52b5f9c87aea2 (diff)
Add ability to extend rule interface in source-compatible manner
-rw-r--r--build2/cli/rule.hxx2
-rw-r--r--libbuild2/adhoc-rule-cxx.hxx2
-rw-r--r--libbuild2/algorithm.cxx9
-rw-r--r--libbuild2/bin/rule.hxx4
-rw-r--r--libbuild2/cc/compile-rule.hxx2
-rw-r--r--libbuild2/cc/link-rule.hxx2
-rw-r--r--libbuild2/dist/rule.hxx2
-rw-r--r--libbuild2/in/rule.hxx2
-rw-r--r--libbuild2/install/rule.hxx6
-rw-r--r--libbuild2/rule.cxx14
-rw-r--r--libbuild2/rule.hxx44
-rw-r--r--libbuild2/test/rule.hxx2
12 files changed, 68 insertions, 23 deletions
diff --git a/build2/cli/rule.hxx b/build2/cli/rule.hxx
index 64f1614..b3ecc2c 100644
--- a/build2/cli/rule.hxx
+++ b/build2/cli/rule.hxx
@@ -23,7 +23,7 @@ namespace build2
// @@ Redo as two separate rules?
//
- class compile_rule: public rule, virtual data
+ class compile_rule: public simple_rule, virtual data
{
public:
compile_rule (data&& d): data (move (d)) {}
diff --git a/libbuild2/adhoc-rule-cxx.hxx b/libbuild2/adhoc-rule-cxx.hxx
index 9b94783..fbcdd4f 100644
--- a/libbuild2/adhoc-rule-cxx.hxx
+++ b/libbuild2/adhoc-rule-cxx.hxx
@@ -18,7 +18,7 @@ namespace build2
//
// Note: exported but should not be used directly (i.e., registered).
//
- class LIBBUILD2_SYMEXPORT cxx_rule: public rule
+ class LIBBUILD2_SYMEXPORT cxx_rule: public simple_rule
{
// For now this class is provided purely as an alias for rule in case the
// implementation (which is also called rule) needs to refer to something
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index de68be2..e1f30e0 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -450,7 +450,8 @@ namespace build2
<< diag_do (a, t);
});
- if (!ru.match (a, t, hint))
+ rule::match_extra me;
+ if (!ru.match (a, t, hint, me))
continue;
}
@@ -479,7 +480,8 @@ namespace build2
//
// @@ Can't we temporarily swap things out in target?
//
- if (!ru1.match (a, t, hint))
+ rule::match_extra me1;
+ if (!ru1.match (a, t, hint, me1))
continue;
}
@@ -527,7 +529,8 @@ namespace build2
<< diag_do (a, t);
});
- return r.second.get ().apply (a, t);
+ rule::match_extra me;
+ return r.second.get ().apply (a, t, me);
}
// If step is true then perform only one step of the match/apply sequence.
diff --git a/libbuild2/bin/rule.hxx b/libbuild2/bin/rule.hxx
index 074b46d..51693a7 100644
--- a/libbuild2/bin/rule.hxx
+++ b/libbuild2/bin/rule.hxx
@@ -18,7 +18,7 @@ namespace build2
// "Fail rule" for obj{}, [h]bmi{}, and libu{} that issues diagnostics if
// someone tries to build any of these groups directly.
//
- class fail_rule: public rule
+ class fail_rule: public simple_rule
{
public:
fail_rule () {}
@@ -32,7 +32,7 @@ namespace build2
// Pass-through to group members rule, similar to alias.
//
- class LIBBUILD2_BIN_SYMEXPORT lib_rule: public rule
+ class LIBBUILD2_BIN_SYMEXPORT lib_rule: public simple_rule
{
public:
lib_rule () {}
diff --git a/libbuild2/cc/compile-rule.hxx b/libbuild2/cc/compile-rule.hxx
index 051b2e3..d6cb002 100644
--- a/libbuild2/cc/compile-rule.hxx
+++ b/libbuild2/cc/compile-rule.hxx
@@ -36,7 +36,7 @@ namespace build2
size_t copied; // First copied-over bmi*{}, 0 if none.
};
- class LIBBUILD2_CC_SYMEXPORT compile_rule: public rule, virtual common
+ class LIBBUILD2_CC_SYMEXPORT compile_rule: public simple_rule, virtual common
{
public:
compile_rule (data&&);
diff --git a/libbuild2/cc/link-rule.hxx b/libbuild2/cc/link-rule.hxx
index ce514b5..7a357a6 100644
--- a/libbuild2/cc/link-rule.hxx
+++ b/libbuild2/cc/link-rule.hxx
@@ -20,7 +20,7 @@ namespace build2
{
namespace cc
{
- class LIBBUILD2_CC_SYMEXPORT link_rule: public rule, virtual common
+ class LIBBUILD2_CC_SYMEXPORT link_rule: public simple_rule, virtual common
{
public:
link_rule (data&&);
diff --git a/libbuild2/dist/rule.hxx b/libbuild2/dist/rule.hxx
index 28caa68..e63016d 100644
--- a/libbuild2/dist/rule.hxx
+++ b/libbuild2/dist/rule.hxx
@@ -23,7 +23,7 @@ namespace build2
// bin::lib_rule for an example). Note that in the latter case the rule
// should "see" all its members for the dist case.
//
- class rule: public build2::rule
+ class rule: public simple_rule
{
public:
rule () {}
diff --git a/libbuild2/in/rule.hxx b/libbuild2/in/rule.hxx
index 653818f..cf67060 100644
--- a/libbuild2/in/rule.hxx
+++ b/libbuild2/in/rule.hxx
@@ -23,7 +23,7 @@ namespace build2
// Note also that currently this rule ignores the dry-run mode (see
// perform_update() for the rationale).
//
- class LIBBUILD2_IN_SYMEXPORT rule: public build2::rule
+ class LIBBUILD2_IN_SYMEXPORT rule: public simple_rule
{
public:
// The rule id is used to form the rule name/version entry in depdb. The
diff --git a/libbuild2/install/rule.hxx b/libbuild2/install/rule.hxx
index 916fc6d..73f2486 100644
--- a/libbuild2/install/rule.hxx
+++ b/libbuild2/install/rule.hxx
@@ -18,7 +18,7 @@ namespace build2
{
namespace install
{
- class LIBBUILD2_SYMEXPORT alias_rule: public rule
+ class LIBBUILD2_SYMEXPORT alias_rule: public simple_rule
{
public:
virtual bool
@@ -46,7 +46,7 @@ namespace build2
static const alias_rule instance;
};
- class fsdir_rule: public rule
+ class fsdir_rule: public simple_rule
{
public:
virtual bool
@@ -95,7 +95,7 @@ namespace build2
struct install_dir;
- class LIBBUILD2_SYMEXPORT file_rule: public rule
+ class LIBBUILD2_SYMEXPORT file_rule: public simple_rule
{
public:
virtual bool
diff --git a/libbuild2/rule.cxx b/libbuild2/rule.cxx
index 9028096..7ccee4e 100644
--- a/libbuild2/rule.cxx
+++ b/libbuild2/rule.cxx
@@ -22,6 +22,20 @@ namespace build2
{
}
+ // simple_rule
+ //
+ bool simple_rule::
+ match (action a, target& t, const string& h, match_extra&) const
+ {
+ return match (a, t, h);
+ }
+
+ recipe simple_rule::
+ apply (action a, target& t, match_extra&) const
+ {
+ return apply (a, t);
+ }
+
// file_rule
//
// Note that this rule is special. It is the last, fallback rule. If
diff --git a/libbuild2/rule.hxx b/libbuild2/rule.hxx
index 8390ea7..298ed6b 100644
--- a/libbuild2/rule.hxx
+++ b/libbuild2/rule.hxx
@@ -16,20 +16,30 @@
namespace build2
{
+ // Rule interface (see also simple_rule below for a simplified version).
+ //
// Once a rule is registered (for a scope), it is treated as immutable. If
// you need to modify some state (e.g., counters or some such), then make
- // sure it is MT-safe.
+ // sure things are MT-safe.
//
// Note: match() is only called once but may not be followed by apply().
//
class LIBBUILD2_SYMEXPORT rule
{
public:
+ // The match_extra argument is used to pass additional information that is
+ // only needed by some rule implementations. It is also a way for us to
+ // later pass more information without breaking source compatibility.
+ //
+ struct match_extra
+ {
+ };
+
virtual bool
- match (action, target&, const string& hint) const = 0;
+ match (action, target&, const string& hint, match_extra&) const = 0;
virtual recipe
- apply (action, target&) const = 0;
+ apply (action, target&, match_extra&) const = 0;
rule () = default;
@@ -40,10 +50,28 @@ namespace build2
rule& operator= (const rule&) = delete;
};
+ // Simplified interface for rules that don't care about the extras.
+ //
+ class LIBBUILD2_SYMEXPORT simple_rule: public rule
+ {
+ public:
+ virtual bool
+ match (action, target&, const string& hint) const = 0;
+
+ virtual recipe
+ apply (action, target&) const = 0;
+
+ virtual bool
+ match (action, target&, const string&, match_extra&) const override;
+
+ virtual recipe
+ apply (action, target&, match_extra&) const override;
+ };
+
// Fallback rule that only matches if the file exists. It will also match
// an mtime_target provided it has a set timestamp.
//
- class LIBBUILD2_SYMEXPORT file_rule: public rule
+ class LIBBUILD2_SYMEXPORT file_rule: public simple_rule
{
public:
virtual bool
@@ -56,7 +84,7 @@ namespace build2
static const file_rule instance;
};
- class LIBBUILD2_SYMEXPORT alias_rule: public rule
+ class LIBBUILD2_SYMEXPORT alias_rule: public simple_rule
{
public:
virtual bool
@@ -72,7 +100,7 @@ namespace build2
// Note that this rule ignores the dry_run flag; see mkdir() in filesystem
// for the rationale.
//
- class LIBBUILD2_SYMEXPORT fsdir_rule: public rule
+ class LIBBUILD2_SYMEXPORT fsdir_rule: public simple_rule
{
public:
virtual bool
@@ -99,7 +127,7 @@ namespace build2
// Fallback rule that always matches and does nothing.
//
- class LIBBUILD2_SYMEXPORT noop_rule: public rule
+ class LIBBUILD2_SYMEXPORT noop_rule: public simple_rule
{
public:
virtual bool
@@ -116,7 +144,7 @@ namespace build2
//
// Note: not exported.
//
- class adhoc_rule: public rule
+ class adhoc_rule: public simple_rule
{
public:
location_value loc; // Buildfile location of the recipe.
diff --git a/libbuild2/test/rule.hxx b/libbuild2/test/rule.hxx
index bc39f50..e96b68b 100644
--- a/libbuild2/test/rule.hxx
+++ b/libbuild2/test/rule.hxx
@@ -16,7 +16,7 @@ namespace build2
{
namespace test
{
- class rule: public build2::rule, protected virtual common
+ class rule: public simple_rule, protected virtual common
{
public:
virtual bool