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#include <assert.h> 16 17#include "eval_env.h" 18 19using namespace std; 20 21string BindingEnv::LookupVariable(const string& var) { 22 map<string, string>::iterator i = bindings_.find(var); 23 if (i != bindings_.end()) 24 return i->second; 25 if (parent_) 26 return parent_->LookupVariable(var); 27 return ""; 28} 29 30void BindingEnv::AddBinding(const string& key, const string& val) { 31 bindings_[key] = val; 32} 33 34void BindingEnv::AddRule(const Rule* rule) { 35 assert(LookupRuleCurrentScope(rule->name()) == NULL); 36 rules_[rule->name()] = rule; 37} 38 39const Rule* BindingEnv::LookupRuleCurrentScope(const string& rule_name) { 40 map<string, const Rule*>::iterator i = rules_.find(rule_name); 41 if (i == rules_.end()) 42 return NULL; 43 return i->second; 44} 45 46const Rule* BindingEnv::LookupRule(const string& rule_name) { 47 map<string, const Rule*>::iterator i = rules_.find(rule_name); 48 if (i != rules_.end()) 49 return i->second; 50 if (parent_) 51 return parent_->LookupRule(rule_name); 52 return NULL; 53} 54 55void Rule::AddBinding(const string& key, const EvalString& val) { 56 bindings_[key] = val; 57} 58 59const EvalString* Rule::GetBinding(const string& key) const { 60 Bindings::const_iterator i = bindings_.find(key); 61 if (i == bindings_.end()) 62 return NULL; 63 return &i->second; 64} 65 66// static 67bool Rule::IsReservedBinding(const string& var) { 68 return var == "command" || 69 var == "depfile" || 70 var == "dyndep" || 71 var == "description" || 72 var == "deps" || 73 var == "generator" || 74 var == "pool" || 75 var == "restat" || 76 var == "rspfile" || 77 var == "rspfile_content" || 78 var == "msvc_deps_prefix"; 79} 80 81const map<string, const Rule*>& BindingEnv::GetRules() const { 82 return rules_; 83} 84 85string BindingEnv::LookupWithFallback(const string& var, 86 const EvalString* eval, 87 Env* env) { 88 map<string, string>::iterator i = bindings_.find(var); 89 if (i != bindings_.end()) 90 return i->second; 91 92 if (eval) 93 return eval->Evaluate(env); 94 95 if (parent_) 96 return parent_->LookupVariable(var); 97 98 return ""; 99} 100 101string EvalString::Evaluate(Env* env) const { 102 string result; 103 for (TokenList::const_iterator i = parsed_.begin(); i != parsed_.end(); ++i) { 104 if (i->second == RAW) 105 result.append(i->first); 106 else 107 result.append(env->LookupVariable(i->first)); 108 } 109 return result; 110} 111 112void EvalString::AddText(StringPiece text) { 113 // Add it to the end of an existing RAW token if possible. 114 if (!parsed_.empty() && parsed_.back().second == RAW) { 115 parsed_.back().first.append(text.str_, text.len_); 116 } else { 117 parsed_.push_back(make_pair(text.AsString(), RAW)); 118 } 119} 120void EvalString::AddSpecial(StringPiece text) { 121 parsed_.push_back(make_pair(text.AsString(), SPECIAL)); 122} 123 124string EvalString::Serialize() const { 125 string result; 126 for (TokenList::const_iterator i = parsed_.begin(); 127 i != parsed_.end(); ++i) { 128 result.append("["); 129 if (i->second == SPECIAL) 130 result.append("$"); 131 result.append(i->first); 132 result.append("]"); 133 } 134 return result; 135} 136 137string EvalString::Unparse() const { 138 string result; 139 for (TokenList::const_iterator i = parsed_.begin(); 140 i != parsed_.end(); ++i) { 141 bool special = (i->second == SPECIAL); 142 if (special) 143 result.append("${"); 144 result.append(i->first); 145 if (special) 146 result.append("}"); 147 } 148 return result; 149} 150