// file : build/scope -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file #ifndef BUILD_SCOPE #define BUILD_SCOPE #include // function #include #include #include #include #include #include #include namespace build { class scope { public: typedef build::path path_type; const path_type& path () const {return i_->first;} // Absolute and normalized. const path_type& src_path () const {return *src_path_;} // Corresponding src path. 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_;} bool root () const {return root_ == this;} // Variable lookup. Note that this find, not find or insert like // in the variable_map, because we also search in outer scopes. // For the latter use the variables map directly. // public: value_proxy operator[] (const std::string&); value_proxy operator[] (const variable&); const path_type* src_path_ {nullptr}; // Cached src_{root,base} var value. public: variable_map variables; prerequisite_set prerequisites; // Meta/operations supported by this project (set on the root // scope only). // meta_operation_table meta_operations; operation_table operations; // 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 buildfiles; // A map of buildfiles to trigger functions that are executed when // such files are sourced. The path must be absolute and normalized. // // The passed path is the buildfile. If the returned value is true, // then the file is sourced. If false -- the file is ignored. Note // that currently triggers can only be registered on the project's // root scope. // using trigger_type = std::function; std::unordered_map triggers; private: friend class scope_map; typedef path_map::const_iterator iterator; scope (): variables (*this) {} iterator i_; scope* parent_; scope* root_; }; class scope_map: public path_map { public: // Note that we assume the first insertion into the map is that // of the global scope. // std::pair insert (const path&, bool root); scope& operator[] (const path& p) {return insert (p, false).first;} // Find the most qualified scope that encompasses this path. // scope& find (const path&); private: typedef path_map base; }; extern scope_map scopes; extern scope* global_scope; } #endif // BUILD_SCOPE