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 
GetOriginStr(VarOrigin origin)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 
Var()40 Var::Var() {
41 }
42 
~Var()43 Var::~Var() {
44 }
45 
AppendVar(Evaluator *,Value *)46 void Var::AppendVar(Evaluator*, Value*) {
47   CHECK(false);
48 }
49 
SimpleVar(VarOrigin origin)50 SimpleVar::SimpleVar(VarOrigin origin)
51     : origin_(origin) {
52 }
53 
SimpleVar(const string & v,VarOrigin origin)54 SimpleVar::SimpleVar(const string& v, VarOrigin origin)
55     : v_(v), origin_(origin) {
56 }
57 
Eval(Evaluator *,string * s) const58 void SimpleVar::Eval(Evaluator*, string* s) const {
59   *s += v_;
60 }
61 
AppendVar(Evaluator * ev,Value * v)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 
String() const69 StringPiece SimpleVar::String() const {
70   return v_;
71 }
72 
DebugString() const73 string SimpleVar::DebugString() const {
74   return v_;
75 }
76 
RecursiveVar(Value * v,VarOrigin origin,StringPiece orig)77 RecursiveVar::RecursiveVar(Value* v, VarOrigin origin, StringPiece orig)
78     : v_(v), origin_(origin), orig_(orig) {
79 }
80 
Eval(Evaluator * ev,string * s) const81 void RecursiveVar::Eval(Evaluator* ev, string* s) const {
82   v_->Eval(ev, s);
83 }
84 
AppendVar(Evaluator *,Value * v)85 void RecursiveVar::AppendVar(Evaluator*, Value* v) {
86   v_ = NewExpr3(v_, NewLiteral(" "), v);
87 }
88 
String() const89 StringPiece RecursiveVar::String() const {
90   return orig_;
91 }
92 
DebugString() const93 string RecursiveVar::DebugString() const {
94   return v_->DebugString();
95 }
96 
UndefinedVar()97 UndefinedVar::UndefinedVar() {}
98 
Eval(Evaluator *,string *) const99 void UndefinedVar::Eval(Evaluator*, string*) const {
100   // Nothing to do.
101 }
102 
String() const103 StringPiece UndefinedVar::String() const {
104   return StringPiece("");
105 }
106 
DebugString() const107 string UndefinedVar::DebugString() const {
108   return "*undefined*";
109 }
110 
~Vars()111 Vars::~Vars() {
112   for (auto p : *this) {
113     delete p.second;
114   }
115 }
116 
add_used_env_vars(Symbol v)117 void Vars::add_used_env_vars(Symbol v) {
118   used_env_vars_.insert(v);
119 }
120 
Lookup(Symbol name) const121 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 
Assign(Symbol name,Var * v)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 
ScopedVar(Vars * vars,Symbol name,Var * var)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 
~ScopedVar()162 ScopedVar::~ScopedVar() {
163   if (orig_) {
164     iter_->second = orig_;
165   } else {
166     vars_->erase(iter_);
167   }
168 }
169