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 using namespace std; 22 23 #include "string_piece.h" 24 25 struct Rule; 26 27 /// An interface for a scope for variable (e.g. "$foo") lookups. 28 struct Env { ~EnvEnv29 virtual ~Env() {} 30 virtual string LookupVariable(const string& var) = 0; 31 }; 32 33 /// A tokenized string that contains variable references. 34 /// Can be evaluated relative to an Env. 35 struct EvalString { 36 /// @return The evaluated string with variable expanded using value found in 37 /// environment @a env. 38 string Evaluate(Env* env) const; 39 40 /// @return The string with variables not expanded. 41 string Unparse() const; 42 ClearEvalString43 void Clear() { parsed_.clear(); } emptyEvalString44 bool empty() const { return parsed_.empty(); } 45 46 void AddText(StringPiece text); 47 void AddSpecial(StringPiece text); 48 49 /// Construct a human-readable representation of the parsed state, 50 /// for use in tests. 51 string Serialize() const; 52 53 private: 54 enum TokenType { RAW, SPECIAL }; 55 typedef vector<pair<string, TokenType> > TokenList; 56 TokenList parsed_; 57 }; 58 59 /// An invokable build command and associated metadata (description, etc.). 60 struct Rule { RuleRule61 explicit Rule(const string& name) : name_(name) {} 62 nameRule63 const string& name() const { return name_; } 64 65 void AddBinding(const string& key, const EvalString& val); 66 67 static bool IsReservedBinding(const string& var); 68 69 const EvalString* GetBinding(const string& key) const; 70 71 private: 72 // Allow the parsers to reach into this object and fill out its fields. 73 friend struct ManifestParser; 74 75 string name_; 76 typedef map<string, EvalString> Bindings; 77 Bindings bindings_; 78 }; 79 80 /// An Env which contains a mapping of variables to values 81 /// as well as a pointer to a parent scope. 82 struct BindingEnv : public Env { BindingEnvBindingEnv83 BindingEnv() : parent_(NULL) {} BindingEnvBindingEnv84 explicit BindingEnv(BindingEnv* parent) : parent_(parent) {} 85 ~BindingEnvBindingEnv86 virtual ~BindingEnv() {} 87 virtual string LookupVariable(const string& var); 88 89 void AddRule(const Rule* rule); 90 const Rule* LookupRule(const string& rule_name); 91 const Rule* LookupRuleCurrentScope(const string& rule_name); 92 const map<string, const Rule*>& GetRules() const; 93 94 void AddBinding(const string& key, const string& val); 95 96 /// This is tricky. Edges want lookup scope to go in this order: 97 /// 1) value set on edge itself (edge_->env_) 98 /// 2) value set on rule, with expansion in the edge's scope 99 /// 3) value set on enclosing scope of edge (edge_->env_->parent_) 100 /// This function takes as parameters the necessary info to do (2). 101 string LookupWithFallback(const string& var, const EvalString* eval, 102 Env* env); 103 104 private: 105 map<string, string> bindings_; 106 map<string, const Rule*> rules_; 107 BindingEnv* parent_; 108 }; 109 110 #endif // NINJA_EVAL_ENV_H_ 111