1 // Copyright 2015 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 // +build ignore 16 17 #include "var.h" 18 19 #include "expr.h" 20 #include "log.h" 21 22 UndefinedVar kUndefinedBuf; 23 UndefinedVar* kUndefined = &kUndefinedBuf; 24 25 const char* GetOriginStr(VarOrigin origin) { 26 switch (origin) { 27 case VarOrigin::UNDEFINED: return "undefined"; 28 case VarOrigin::DEFAULT: return "default"; 29 case VarOrigin::ENVIRONMENT: return "environment"; 30 case VarOrigin::ENVIRONMENT_OVERRIDE: return "environment override"; 31 case VarOrigin::FILE: return "file"; 32 case VarOrigin::COMMAND_LINE: return "command line"; 33 case VarOrigin::OVERRIDE: return "override"; 34 case VarOrigin::AUTOMATIC: return "automatic"; 35 } 36 CHECK(false); 37 return "*** broken origin ***"; 38 } 39 40 Var::Var() { 41 } 42 43 Var::~Var() { 44 } 45 46 void Var::AppendVar(Evaluator*, Value*) { 47 CHECK(false); 48 } 49 50 SimpleVar::SimpleVar(VarOrigin origin) 51 : origin_(origin) { 52 } 53 54 SimpleVar::SimpleVar(const string& v, VarOrigin origin) 55 : v_(v), origin_(origin) { 56 } 57 58 void SimpleVar::Eval(Evaluator*, string* s) const { 59 *s += v_; 60 } 61 62 void SimpleVar::AppendVar(Evaluator* ev, Value* v) { 63 string buf; 64 v->Eval(ev, &buf); 65 v_.push_back(' '); 66 v_ += buf; 67 } 68 69 StringPiece SimpleVar::String() const { 70 return v_; 71 } 72 73 string SimpleVar::DebugString() const { 74 return v_; 75 } 76 77 RecursiveVar::RecursiveVar(Value* v, VarOrigin origin, StringPiece orig) 78 : v_(v), origin_(origin), orig_(orig) { 79 } 80 81 void RecursiveVar::Eval(Evaluator* ev, string* s) const { 82 v_->Eval(ev, s); 83 } 84 85 void RecursiveVar::AppendVar(Evaluator*, Value* v) { 86 v_ = NewExpr3(v_, NewLiteral(" "), v); 87 } 88 89 StringPiece RecursiveVar::String() const { 90 return orig_; 91 } 92 93 string RecursiveVar::DebugString() const { 94 return v_->DebugString(); 95 } 96 97 UndefinedVar::UndefinedVar() {} 98 99 void UndefinedVar::Eval(Evaluator*, string*) const { 100 // Nothing to do. 101 } 102 103 StringPiece UndefinedVar::String() const { 104 return StringPiece(""); 105 } 106 107 string UndefinedVar::DebugString() const { 108 return "*undefined*"; 109 } 110 111 Vars::~Vars() { 112 for (auto p : *this) { 113 delete p.second; 114 } 115 } 116 117 void Vars::add_used_env_vars(Symbol v) { 118 used_env_vars_.insert(v); 119 } 120 121 Var* Vars::Lookup(Symbol name) const { 122 auto found = find(name); 123 if (found == end()) 124 return kUndefined; 125 Var* v = found->second; 126 if (v->Origin() == VarOrigin::ENVIRONMENT || 127 v->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) { 128 used_env_vars_.insert(name); 129 } 130 return v; 131 } 132 133 void Vars::Assign(Symbol name, Var* v) { 134 auto p = emplace(name, v); 135 if (!p.second) { 136 Var* orig = p.first->second; 137 if (orig->Origin() == VarOrigin::OVERRIDE || 138 orig->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) { 139 return; 140 } 141 if (orig->Origin() == VarOrigin::AUTOMATIC) { 142 ERROR("overriding automatic variable is not implemented yet"); 143 } 144 if (orig->IsDefined()) 145 delete p.first->second; 146 p.first->second = v; 147 } 148 } 149 150 unordered_set<Symbol> Vars::used_env_vars_; 151 152 ScopedVar::ScopedVar(Vars* vars, Symbol name, Var* var) 153 : vars_(vars), orig_(NULL) { 154 auto p = vars->emplace(name, var); 155 iter_ = p.first; 156 if (!p.second) { 157 orig_ = iter_->second; 158 iter_->second = var; 159 } 160 } 161 162 ScopedVar::~ScopedVar() { 163 if (orig_) { 164 iter_->second = orig_; 165 } else { 166 vars_->erase(iter_); 167 } 168 } 169