diff options
Diffstat (limited to 'libbuild2/operation.hxx')
-rw-r--r-- | libbuild2/operation.hxx | 143 |
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 |