aboutsummaryrefslogtreecommitdiff
path: root/build/scope
diff options
context:
space:
mode:
Diffstat (limited to 'build/scope')
-rw-r--r--build/scope312
1 files changed, 0 insertions, 312 deletions
diff --git a/build/scope b/build/scope
deleted file mode 100644
index 0cb319f..0000000
--- a/build/scope
+++ /dev/null
@@ -1,312 +0,0 @@
-// file : build/scope -*- C++ -*-
-// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD_SCOPE
-#define BUILD_SCOPE
-
-#include <functional> // function
-#include <unordered_set>
-#include <unordered_map>
-
-#include <butl/path-map>
-
-#include <build/types>
-#include <build/utility>
-
-#include <build/module>
-#include <build/variable>
-#include <build/prerequisite>
-#include <build/target-type>
-#include <build/rule-map>
-#include <build/operation>
-
-namespace build
-{
- class scope
- {
- public:
- // Absolute and normalized.
- //
- const dir_path&
- out_path () const {return *out_path_;}
-
- const dir_path&
- src_path () const {return *src_path_;}
-
- // These are pointers to the keys in scope_map.
- //
- const dir_path* out_path_ {nullptr};
- const dir_path* src_path_ {nullptr};
-
- bool
- root () const {return root_ == this;}
-
- scope*
- parent_scope () const {return parent_;}
-
- // Root scope of this scope or NULL if this scope is not (yet)
- // in any (known) project. Note that if the scope itself is
- // root, then this function return this. To get to the outer
- // root, query the root scope of the parent.
- //
- scope*
- root_scope () const {return root_;}
-
- // Root scope of a strong amalgamation of this scope or NULL if
- // this scope is not (yet) in any (known) project. If there is
- // no strong amalgamation, then this function returns the root
- // scope of the project (in other words, in this case a project
- // is treated as its own strong amalgamation).
- //
- scope*
- strong_scope () const
- {
- return root_ != nullptr
- ? root_->strong_ != nullptr ? root_->strong_ : root_
- : nullptr;
- }
-
- // Root scope of the outermost amalgamation or NULL if this scope is not
- // (yet) in any (known) project. If there is no amalgamation, then this
- // function returns the root scope of the project (in other words, in this
- // case a project is treated as its own amalgamation).
- //
- scope*
- weak_scope () const
- {
- scope* r (root_);
- if (r != nullptr)
- for (; r->parent_->root_ != nullptr; r = r->parent_->root_) ;
- return r;
- }
-
- // Variables.
- //
- public:
- variable_map vars;
-
- // Lookup, including in outer scopes. If you only want to lookup
- // in this scope, do it on the the variables map directly.
- //
- build::lookup<const value>
- operator[] (const variable& var) const
- {
- return lookup (nullptr, nullptr, var);
- }
-
- build::lookup<const value>
- operator[] (const std::string& name) const
- {
- return operator[] (var_pool.find (name));
- }
-
- // As above, but includes target type/pattern-specific variables.
- //
- build::lookup<const value>
- lookup (const target_key& tk, const variable& var) const
- {
- return lookup (tk.type, tk.name, var);
- }
-
- build::lookup<const value>
- lookup (const target_key& tk, const string& var) const
- {
- return lookup (tk, var_pool.find (var));
- }
-
- build::lookup<const value>
- lookup (const target_type& tt,
- const string& name,
- const variable& var) const
- {
- return lookup (&tt, &name, var);
- }
-
- build::lookup<const value>
- lookup (const target_type& tt, const string& name, const string& var) const
- {
- return lookup (tt, name, var_pool.find (var));
- }
-
- build::lookup<const value>
- lookup (const target_type*, const string* name, const variable&) const;
-
- // Return a value suitable for assignment (or append if you only
- // want to append to the value from this scope). If the variable
- // does not exist in this scope's map, then a new one with the
- // NULL value is added and returned. Otherwise the existing value
- // is returned.
- //
- value&
- assign (const variable& var) {return vars.assign (var).first.get ();}
-
- value&
- assign (const std::string& name) {return vars.assign (name).first.get ();}
-
- // Return a value suitable for appending. If the variable does not
- // exist in this scope's map, then outer scopes are searched for
- // the same variable. If found then a new variable with the found
- // value is added to this scope and returned. Otherwise this
- // function proceeds as assign().
- //
- value&
- append (const variable&);
-
- value&
- append (const std::string& name)
- {
- return append (var_pool.find (name));
- }
-
- // Target type/pattern-specific variables.
- //
- variable_type_map target_vars;
-
- // Prerequisite cache.
- //
- public:
- prerequisite_set prerequisites;
-
- // Meta/operations supported by this project (set on the root
- // scope only).
- //
- build::meta_operations meta_operations;
- build::operations operations;
-
- typedef build::path path_type;
-
- // Set of buildfiles already loaded for this scope. The included
- // buildfiles are checked against the project's root scope while
- // imported -- against the global scope (global_scope).
- //
- std::unordered_set<path_type> buildfiles;
-
- // Target types.
- //
- public:
- target_type_map target_types;
-
- const target_type*
- find_target_type (const string&, const scope** = nullptr) const;
-
- // Given a name, figure out its type, taking into account extensions,
- // special names (e.g., '.' and '..'), or anything else that might be
- // relevant. Also process the name (in place) by extracting the
- // extension, adjusting dir/value, etc., (note that the dir is not
- // necessarily normalized). Return NULL if not found.
- //
- const target_type*
- find_target_type (name&, const string*& ext) const;
-
- // Rules.
- //
- public:
- rule_map rules;
-
- // Modules.
- //
- public:
- loaded_module_map modules; // Only on root scope.
-
- public:
- bool
- empty () const
- {
- return
- vars.empty () &&
- target_vars.empty () &&
- prerequisites.empty () &&
- meta_operations.empty () &&
- operations.empty () &&
- buildfiles.empty () &&
- target_types.empty () &&
- rules.empty () &&
- modules.empty ();
- }
-
- private:
- friend class scope_map;
- friend class temp_scope;
-
- // These two from <build/file> set strong_.
- //
- friend void create_bootstrap_outer (scope&);
- friend scope& create_bootstrap_inner (scope&, const dir_path&);
-
- scope () = default;
-
- scope* parent_;
- scope* root_;
- scope* strong_ = nullptr; // Only set on root sopes.
- // NULL means no strong amalgamtion.
- };
-
- // Temporary scope. The idea is to be able to create a temporary
- // scope in order not to change the variables in the current scope.
- // Such a scope is not entered in to the scope map. As a result it
- // can only be used as a temporary set of variables. In particular,
- // defining targets/prerequisites directly in such a scope will surely
- // end up badly. Defining any nested scopes will be as if defining
- // such a scope in the parent (since path() returns parent's path).
- //
- class temp_scope: public scope
- {
- public:
- temp_scope (scope& p)
- {
- out_path_ = p.out_path_;
- src_path_ = p.src_path_;
- parent_ = &p;
- root_ = p.root_;
- // No need to copy strong_ since we are never root scope.
- }
- };
-
- class scope_map
- {
- public:
- using map_type = butl::dir_path_map<scope*>;
- using iterator = map_type::iterator;
- using const_iterator = map_type::const_iterator;
-
- // Note that we assume the first insertion into the map is that
- // of the global scope. If the passed scope pointer is not NULL,
- // then insert this scope instead of a new one.
- //
- iterator
- insert (const dir_path&, scope*, bool parent, bool root);
-
- // Find the most qualified scope that encompasses this path.
- //
- scope&
- find (const dir_path&) const;
-
- scope&
- find (const path& p) const
- {
- // Natural thing to do here would be to call find (p.directory ()).
- // However, there could be a situation where the passed path is a
- // directory (i.e., the calling code does not know what it is dealing
- // with), so let's use the whole path.
- //
- return find (dir_path (p.string ()));
- }
-
- const_iterator begin () const {return map_.begin ();}
- const_iterator end () const {return map_.end ();}
-
- void
- clear ();
-
- ~scope_map () {clear ();}
-
- private:
- map_type map_;
- };
-
- extern scope_map scopes;
- extern scope* global_scope;
-}
-
-#endif // BUILD_SCOPE