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 22UndefinedVar kUndefinedBuf; 23UndefinedVar* kUndefined = &kUndefinedBuf; 24 25const 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 40Var::Var() : readonly_(false) { 41} 42 43Var::~Var() { 44} 45 46void Var::AppendVar(Evaluator*, Value*) { 47 CHECK(false); 48} 49 50SimpleVar::SimpleVar(VarOrigin origin) 51 : origin_(origin) { 52} 53 54SimpleVar::SimpleVar(const string& v, VarOrigin origin) 55 : v_(v), origin_(origin) { 56} 57 58void SimpleVar::Eval(Evaluator*, string* s) const { 59 *s += v_; 60} 61 62void SimpleVar::AppendVar(Evaluator* ev, Value* v) { 63 string buf; 64 v->Eval(ev, &buf); 65 v_.push_back(' '); 66 v_ += buf; 67} 68 69StringPiece SimpleVar::String() const { 70 return v_; 71} 72 73string SimpleVar::DebugString() const { 74 return v_; 75} 76 77RecursiveVar::RecursiveVar(Value* v, VarOrigin origin, StringPiece orig) 78 : v_(v), origin_(origin), orig_(orig) { 79} 80 81void RecursiveVar::Eval(Evaluator* ev, string* s) const { 82 v_->Eval(ev, s); 83} 84 85void RecursiveVar::AppendVar(Evaluator*, Value* v) { 86 v_ = NewExpr3(v_, NewLiteral(" "), v); 87} 88 89StringPiece RecursiveVar::String() const { 90 return orig_; 91} 92 93string RecursiveVar::DebugString() const { 94 return v_->DebugString(); 95} 96 97UndefinedVar::UndefinedVar() {} 98 99void UndefinedVar::Eval(Evaluator*, string*) const { 100 // Nothing to do. 101} 102 103StringPiece UndefinedVar::String() const { 104 return StringPiece(""); 105} 106 107string UndefinedVar::DebugString() const { 108 return "*undefined*"; 109} 110 111Vars::~Vars() { 112 for (auto p : *this) { 113 delete p.second; 114 } 115} 116 117void Vars::add_used_env_vars(Symbol v) { 118 used_env_vars_.insert(v); 119} 120 121Var* 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 133void Vars::Assign(Symbol name, Var* v, bool* readonly) { 134 *readonly = false; 135 auto p = emplace(name, v); 136 if (!p.second) { 137 Var* orig = p.first->second; 138 if (orig->ReadOnly()) { 139 *readonly = true; 140 return; 141 } 142 if (orig->Origin() == VarOrigin::OVERRIDE || 143 orig->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) { 144 return; 145 } 146 if (orig->Origin() == VarOrigin::AUTOMATIC) { 147 ERROR("overriding automatic variable is not implemented yet"); 148 } 149 if (orig->IsDefined()) 150 delete p.first->second; 151 p.first->second = v; 152 } 153} 154 155unordered_set<Symbol> Vars::used_env_vars_; 156 157ScopedVar::ScopedVar(Vars* vars, Symbol name, Var* var) 158 : vars_(vars), orig_(NULL) { 159 auto p = vars->emplace(name, var); 160 iter_ = p.first; 161 if (!p.second) { 162 orig_ = iter_->second; 163 iter_->second = var; 164 } 165} 166 167ScopedVar::~ScopedVar() { 168 if (orig_) { 169 iter_->second = orig_; 170 } else { 171 vars_->erase(iter_); 172 } 173} 174