1 // Copyright 2011 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef NINJA_EVAL_ENV_H_ 16 #define NINJA_EVAL_ENV_H_ 17 18 #include <map> 19 #include <string> 20 #include <vector> 21 22 #include "string_piece.h" 23 24 struct Rule; 25 26 /// An interface for a scope for variable (e.g. "$foo") lookups. 27 struct Env { ~EnvEnv28 virtual ~Env() {} 29 virtual std::string LookupVariable(const std::string& var) = 0; 30 }; 31 32 /// A tokenized string that contains variable references. 33 /// Can be evaluated relative to an Env. 34 struct EvalString { 35 /// @return The evaluated string with variable expanded using value found in 36 /// environment @a env. 37 std::string Evaluate(Env* env) const; 38 39 /// @return The string with variables not expanded. 40 std::string Unparse() const; 41 ClearEvalString42 void Clear() { parsed_.clear(); } emptyEvalString43 bool empty() const { return parsed_.empty(); } 44 45 void AddText(StringPiece text); 46 void AddSpecial(StringPiece text); 47 48 /// Construct a human-readable representation of the parsed state, 49 /// for use in tests. 50 std::string Serialize() const; 51 52 private: 53 enum TokenType { RAW, SPECIAL }; 54 typedef std::vector<std::pair<std::string, TokenType> > TokenList; 55 TokenList parsed_; 56 }; 57 58 /// An invocable build command and associated metadata (description, etc.). 59 struct Rule { RuleRule60 explicit Rule(const std::string& name) : name_(name) {} 61 nameRule62 const std::string& name() const { return name_; } 63 64 void AddBinding(const std::string& key, const EvalString& val); 65 66 static bool IsReservedBinding(const std::string& var); 67 68 const EvalString* GetBinding(const std::string& key) const; 69 70 private: 71 // Allow the parsers to reach into this object and fill out its fields. 72 friend struct ManifestParser; 73 74 std::string name_; 75 typedef std::map<std::string, EvalString> Bindings; 76 Bindings bindings_; 77 }; 78 79 /// An Env which contains a mapping of variables to values 80 /// as well as a pointer to a parent scope. 81 struct BindingEnv : public Env { BindingEnvBindingEnv82 BindingEnv() : parent_(NULL) {} BindingEnvBindingEnv83 explicit BindingEnv(BindingEnv* parent) : parent_(parent) {} 84 ~BindingEnvBindingEnv85 virtual ~BindingEnv() {} 86 virtual std::string LookupVariable(const std::string& var); 87 88 void AddRule(const Rule* rule); 89 const Rule* LookupRule(const std::string& rule_name); 90 const Rule* LookupRuleCurrentScope(const std::string& rule_name); 91 const std::map<std::string, const Rule*>& GetRules() const; 92 93 void AddBinding(const std::string& key, const std::string& val); 94 95 /// This is tricky. Edges want lookup scope to go in this order: 96 /// 1) value set on edge itself (edge_->env_) 97 /// 2) value set on rule, with expansion in the edge's scope 98 /// 3) value set on enclosing scope of edge (edge_->env_->parent_) 99 /// This function takes as parameters the necessary info to do (2). 100 std::string LookupWithFallback(const std::string& var, const EvalString* eval, 101 Env* env); 102 103 private: 104 std::map<std::string, std::string> bindings_; 105 std::map<std::string, const Rule*> rules_; 106 BindingEnv* parent_; 107 }; 108 109 #endif // NINJA_EVAL_ENV_H_ 110