aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/operation.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/operation.hxx')
-rw-r--r--libbuild2/operation.hxx143
1 files changed, 97 insertions, 46 deletions
diff --git a/libbuild2/operation.hxx b/libbuild2/operation.hxx
index de3ae7c..e8ff38a 100644
--- a/libbuild2/operation.hxx
+++ b/libbuild2/operation.hxx
@@ -4,7 +4,7 @@
#ifndef LIBBUILD2_OPERATION_HXX
#define LIBBUILD2_OPERATION_HXX
-#include <libbutl/string-table.mxx>
+#include <libbutl/string-table.hxx>
#include <libbuild2/types.hxx>
#include <libbuild2/forward.hxx>
@@ -82,8 +82,8 @@ namespace build2
// then default_id is used. If, however, operation_pre() is NULL,
// then default_id is translated to update_id.
//
- void (*meta_operation_pre) (const values&, const location&);
- operation_id (*operation_pre) (const values&, operation_id);
+ void (*meta_operation_pre) (context&, const values&, const location&);
+ operation_id (*operation_pre) (context&, const values&, operation_id);
// Meta-operation-specific logic to load the buildfile, search and match
// the targets, and execute the action on the targets.
@@ -121,16 +121,20 @@ namespace build2
// End of operation and meta-operation batches.
//
- void (*operation_post) (const values&, operation_id);
- void (*meta_operation_post) (const values&);
+ // Note: not called in case any of the earlier callbacks failed.
+ //
+ void (*operation_post) (context&, const values&, operation_id);
+ void (*meta_operation_post) (context&, const values&);
- // Optional prerequisite inclusion/exclusion override callback. See
- // include() for details.
+ // Optional prerequisite exclusion override callback. See include() for
+ // details. Note that it's not called for include_type::normal without
+ // operation-specific override.
//
include_type (*include) (action,
const target&,
const prerequisite_member&,
- include_type);
+ include_type,
+ lookup&);
};
// Built-in meta-operations.
@@ -145,41 +149,46 @@ namespace build2
// scope.
//
LIBBUILD2_SYMEXPORT void
- load (const values&,
- scope&,
- const path&,
- const dir_path&,
- const dir_path&,
- const location&);
+ perform_load (const values&,
+ scope&,
+ const path&,
+ const dir_path&,
+ const dir_path&,
+ const location&);
// Search and match the target. This is the default implementation
// that does just that and adds a pointer to the target to the list.
//
LIBBUILD2_SYMEXPORT void
- search (const values&,
- const scope&,
- const scope&,
- const path&,
- const target_key&,
- const location&,
- action_targets&);
+ perform_search (const values&,
+ const scope&,
+ const scope&,
+ const path&,
+ const target_key&,
+ const location&,
+ action_targets&);
LIBBUILD2_SYMEXPORT void
- match (const values&, action, action_targets&,
- uint16_t diag, bool prog);
+ perform_match (const values&, action, action_targets&,
+ uint16_t diag, bool prog);
// Execute the action on the list of targets. This is the default
// implementation that does just that while issuing appropriate
// diagnostics (unless quiet).
//
LIBBUILD2_SYMEXPORT void
- execute (const values&, action, const action_targets&,
- uint16_t diag, bool prog);
+ perform_execute (const values&, action, const action_targets&,
+ uint16_t diag, bool prog);
LIBBUILD2_SYMEXPORT extern const meta_operation_info mo_noop;
LIBBUILD2_SYMEXPORT extern const meta_operation_info mo_perform;
LIBBUILD2_SYMEXPORT extern const meta_operation_info mo_info;
+ // Return true if params does not contain no_subprojects.
+ //
+ LIBBUILD2_SYMEXPORT bool
+ info_subprojects (const values& params);
+
// Operation info.
//
// NOTE: keep POD-like to ensure can be constant-initialized in order to
@@ -216,17 +225,38 @@ namespace build2
//
const size_t concurrency;
- // The first argument in all the callbacks is the operation parameters.
+ // The values argument in the callbacks is the operation parameters. If
+ // the operation expects parameters, then it should have a non-NULL
+ // operation_pre() callback. Failed that, any parameters will be diagnosed
+ // as unexpected.
+ //
+ // Note also that if the specified operation has outer (for example,
+ // update-for-install), then parameters belong to outer (for example,
+ // install; this is done in order to be consistent with the case when
+ // update is performed as a pre-operation of install).
+
+ // Pre/post operations for this operation. Note that these callbacks are
+ // called before this operation becomes current.
+ //
+ // If the returned by pre/post_*() operation_id's are not 0, then they are
+ // injected as pre/post operations for this operation. Can be NULL if
+ // unused. The returned operation_id shall not be default_id.
//
- // If the operation expects parameters, then it should have a non-NULL
- // pre(). Failed that, any parameters will be diagnosed as unexpected.
+ operation_id (*pre_operation) (
+ context&, const values&, meta_operation_id, const location&);
- // If the returned operation_id's are not 0, then they are injected
- // as pre/post operations for this operation. Can be NULL if unused.
- // The returned operation_id shall not be default_id.
+ operation_id (*post_operation) (
+ context&, const values&, meta_operation_id);
+
+ // Called immediately after/before this operation becomes/ceases to be
+ // current operation for the specified context. Can be used to
+ // initialize/finalize operation-specific data (context::current_*_odata).
+ // Can be NULL if unused.
//
- operation_id (*pre) (const values&, meta_operation_id, const location&);
- operation_id (*post) (const values&, meta_operation_id);
+ void (*operation_pre) (
+ context&, const values&, bool inner, const location&);
+ void (*operation_post) (
+ context&, const values&, bool inner);
// Operation-specific ad hoc rule callbacks. Essentially, if not NULL,
// then every ad hoc rule match and apply call for this operation is
@@ -302,35 +332,36 @@ namespace build2
using operation_table = butl::string_table<operation_id>;
- // These are "sparse" in the sense that we may have "holes" that
- // are represented as NULL pointers. Also, lookup out of bounds
- // is treated as a hole.
+ // This is a "sparse" vector in the sense that we may have "holes" that are
+ // represented as default-initialized empty instances (for example, NULL if
+ // T is a pointer). Also, lookup out of bounds is treated as a hole.
//
- template <typename T>
+ template <typename T, size_t N>
struct sparse_vector
{
- using base_type = vector<T*>;
+ using base_type = small_vector<T, N>;
using size_type = typename base_type::size_type;
void
- insert (size_type i, T& x)
+ insert (size_type i, T x)
{
size_type n (v_.size ());
if (i < n)
- v_[i] = &x;
+ v_[i] = x;
else
{
if (n != i)
- v_.resize (i, nullptr); // Add holes.
- v_.push_back (&x);
+ v_.resize (i, T ()); // Add holes.
+
+ v_.push_back (move (x));
}
}
- T*
+ T
operator[] (size_type i) const
{
- return i < v_.size () ? v_[i] : nullptr;
+ return i < v_.size () ? v_[i] : T ();
}
bool
@@ -345,8 +376,28 @@ namespace build2
base_type v_;
};
- using meta_operations = sparse_vector<const meta_operation_info>;
- using operations = sparse_vector<const operation_info>;
+ // For operations we keep both the pointer to its description as well
+ // as to its operation variable (see var_include) which may belong to
+ // the project-private variable pool.
+ //
+ struct project_operation_info
+ {
+ const operation_info* info = nullptr;
+ const variable* ovar = nullptr; // Operation variable.
+
+ // Allow treating it as pointer to operation_info in most contexts.
+ //
+ operator const operation_info*() const {return info;}
+ bool operator== (nullptr_t) {return info == nullptr;}
+ bool operator!= (nullptr_t) {return info != nullptr;}
+
+ project_operation_info (const operation_info* i = nullptr, // VC14
+ const variable* v = nullptr)
+ : info (i), ovar (v) {}
+ };
+
+ using meta_operations = sparse_vector<const meta_operation_info*, 8>;
+ using operations = sparse_vector<project_operation_info, 10>;
}
namespace butl