blob: 10b903b5323748ec3efcb5d5484809305d66d8b7 [file] [log] [blame]
Shinichiro Hamaji1d545aa2015-06-23 15:29:13 +09001// 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
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090015// +build ignore
16
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090017#include "var.h"
18
Dan Willemsen276e96a2017-10-03 14:24:48 -070019#include "eval.h"
Shinichiro Hamaji645cca72015-09-24 17:04:21 +090020#include "expr.h"
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +090021#include "log.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090022
Dan Willemsenee57a3f2018-11-05 16:18:44 -080023unordered_map<const Var*, string> Var::diagnostic_messages_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090024
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090025const char* GetOriginStr(VarOrigin origin) {
26 switch (origin) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -070027 case VarOrigin::UNDEFINED:
28 return "undefined";
29 case VarOrigin::DEFAULT:
30 return "default";
31 case VarOrigin::ENVIRONMENT:
32 return "environment";
33 case VarOrigin::ENVIRONMENT_OVERRIDE:
34 return "environment override";
35 case VarOrigin::FILE:
36 return "file";
37 case VarOrigin::COMMAND_LINE:
38 return "command line";
39 case VarOrigin::OVERRIDE:
40 return "override";
41 case VarOrigin::AUTOMATIC:
42 return "automatic";
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +090043 }
44 CHECK(false);
45 return "*** broken origin ***";
46}
47
Sasha Smundakae1d58c2018-08-22 09:39:42 -070048Var::Var() : Var(VarOrigin::UNDEFINED) {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090049
Dan Willemsenee57a3f2018-11-05 16:18:44 -080050Var::Var(VarOrigin origin)
51 : origin_(origin), readonly_(false), deprecated_(false), obsolete_(false) {}
Sasha Smundakae1d58c2018-08-22 09:39:42 -070052
53Var::~Var() {
54 diagnostic_messages_.erase(this);
55}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090056
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +090057void Var::AppendVar(Evaluator*, Value*) {
58 CHECK(false);
59}
60
Sasha Smundakae1d58c2018-08-22 09:39:42 -070061void Var::SetDeprecated(const StringPiece& msg) {
62 deprecated_ = true;
63 diagnostic_messages_[this] = msg.as_string();
64}
65
66void Var::SetObsolete(const StringPiece& msg) {
67 obsolete_ = true;
68 diagnostic_messages_[this] = msg.as_string();
69}
70
Sasha Smundakae1d58c2018-08-22 09:39:42 -070071void Var::Used(Evaluator* ev, const Symbol& sym) const {
72 if (obsolete_) {
Dan Willemsenee57a3f2018-11-05 16:18:44 -080073 ev->Error(StringPrintf("*** %s is obsolete%s.", sym.c_str(),
74 diagnostic_message_text()));
Sasha Smundakae1d58c2018-08-22 09:39:42 -070075 } else if (deprecated_) {
Dan Willemsenee57a3f2018-11-05 16:18:44 -080076 WARN_LOC(ev->loc(), "%s has been deprecated%s.", sym.c_str(),
77 diagnostic_message_text());
Sasha Smundakae1d58c2018-08-22 09:39:42 -070078 }
79}
80
Dan Willemsenee57a3f2018-11-05 16:18:44 -080081const char* Var::diagnostic_message_text() const {
Sasha Smundakae1d58c2018-08-22 09:39:42 -070082 auto it = diagnostic_messages_.find(this);
83 return it == diagnostic_messages_.end() ? "" : it->second.c_str();
84}
85
86const string& Var::DeprecatedMessage() const {
87 static const string empty_string;
88 auto it = diagnostic_messages_.find(this);
89 return it == diagnostic_messages_.end() ? empty_string : it->second;
90}
91
Dan Willemsenee57a3f2018-11-05 16:18:44 -080092Var* Var::Undefined() {
93 static Var* undefined_var;
Sasha Smundakae1d58c2018-08-22 09:39:42 -070094 if (!undefined_var) {
95 undefined_var = new UndefinedVar();
96 }
97 return undefined_var;
98}
99
100SimpleVar::SimpleVar(VarOrigin origin) : Var(origin) {}
Shinichiro Hamaji90e52ce2016-02-10 13:53:41 +0900101
Dan Willemsenee57a3f2018-11-05 16:18:44 -0800102SimpleVar::SimpleVar(const string& v, VarOrigin origin) : Var(origin), v_(v) {}
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700103
Dan Willemsenee57a3f2018-11-05 16:18:44 -0800104SimpleVar::SimpleVar(VarOrigin origin, Evaluator* ev, Value* v) : Var(origin) {
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700105 v->Eval(ev, &v_);
106}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900107
Dan Willemsen36e57292017-10-09 11:23:32 -0700108void SimpleVar::Eval(Evaluator* ev, string* s) const {
109 ev->CheckStack();
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900110 *s += v_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900111}
112
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +0900113void SimpleVar::AppendVar(Evaluator* ev, Value* v) {
Shinichiro Hamajie6a4d172016-03-10 14:47:34 +0900114 string buf;
115 v->Eval(ev, &buf);
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900116 v_.push_back(' ');
Shinichiro Hamajie6a4d172016-03-10 14:47:34 +0900117 v_ += buf;
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +0900118}
119
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900120StringPiece SimpleVar::String() const {
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900121 return v_;
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900122}
123
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900124string SimpleVar::DebugString() const {
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900125 return v_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900126}
127
Shinichiro Hamajif62e9a72015-06-26 04:18:21 +0900128RecursiveVar::RecursiveVar(Value* v, VarOrigin origin, StringPiece orig)
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700129 : Var(origin), v_(v), orig_(orig) {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900130
131void RecursiveVar::Eval(Evaluator* ev, string* s) const {
Dan Willemsen36e57292017-10-09 11:23:32 -0700132 ev->CheckStack();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900133 v_->Eval(ev, s);
134}
135
Dan Willemsen36e57292017-10-09 11:23:32 -0700136void RecursiveVar::AppendVar(Evaluator* ev, Value* v) {
137 ev->CheckStack();
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700138 v_ = Value::NewExpr(v_, Value::NewLiteral(" "), v);
Shinichiro Hamaji4c469b32015-06-15 19:53:36 +0900139}
140
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900141StringPiece RecursiveVar::String() const {
142 return orig_;
143}
144
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900145string RecursiveVar::DebugString() const {
Sasha Smundak8174f9b2018-08-13 11:07:30 -0700146 return Value::DebugString(v_);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900147}
148
149UndefinedVar::UndefinedVar() {}
150
151void UndefinedVar::Eval(Evaluator*, string*) const {
152 // Nothing to do.
153}
154
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900155StringPiece UndefinedVar::String() const {
Shinichiro Hamaji388e8582015-07-03 16:51:46 +0900156 return StringPiece("");
Shinichiro Hamaji81699be2015-06-22 18:07:38 +0900157}
158
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900159string UndefinedVar::DebugString() const {
160 return "*undefined*";
161}
162
163Vars::~Vars() {
164 for (auto p : *this) {
165 delete p.second;
166 }
167}
168
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900169void Vars::add_used_env_vars(Symbol v) {
170 used_env_vars_.insert(v);
171}
172
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900173Var* Vars::Lookup(Symbol name) const {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900174 auto found = find(name);
175 if (found == end())
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700176 return Var::Undefined();
Shinichiro Hamaji5163e042015-07-14 03:51:44 +0900177 Var* v = found->second;
178 if (v->Origin() == VarOrigin::ENVIRONMENT ||
179 v->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) {
180 used_env_vars_.insert(name);
181 }
182 return v;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900183}
184
Dan Willemsenff90ea32017-11-21 13:22:26 -0800185Var* Vars::Peek(Symbol name) const {
186 auto found = find(name);
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700187 return found == end() ? Var::Undefined() : found->second;
Dan Willemsenff90ea32017-11-21 13:22:26 -0800188}
189
Dan Willemsenf87d49e2016-09-29 20:09:47 -0700190void Vars::Assign(Symbol name, Var* v, bool* readonly) {
191 *readonly = false;
Shinichiro Hamaji3deff5b2016-02-17 17:50:06 +0900192 auto p = emplace(name, v);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900193 if (!p.second) {
Shinichiro Hamaji0ea9e912015-06-26 04:24:38 +0900194 Var* orig = p.first->second;
Dan Willemsenf87d49e2016-09-29 20:09:47 -0700195 if (orig->ReadOnly()) {
196 *readonly = true;
197 return;
198 }
Shinichiro Hamaji0ea9e912015-06-26 04:24:38 +0900199 if (orig->Origin() == VarOrigin::OVERRIDE ||
200 orig->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) {
201 return;
202 }
Shinichiro Hamaji2bb8f372015-06-26 06:58:13 +0900203 if (orig->Origin() == VarOrigin::AUTOMATIC) {
204 ERROR("overriding automatic variable is not implemented yet");
205 }
Shinichiro Hamaji0ea9e912015-06-26 04:24:38 +0900206 if (orig->IsDefined())
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900207 delete p.first->second;
208 p.first->second = v;
209 }
210}
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +0900211
Sasha Smundak8174f9b2018-08-13 11:07:30 -0700212SymbolSet Vars::used_env_vars_;
Shinichiro Hamaji5163e042015-07-14 03:51:44 +0900213
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900214ScopedVar::ScopedVar(Vars* vars, Symbol name, Var* var)
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +0900215 : vars_(vars), orig_(NULL) {
Shinichiro Hamaji3deff5b2016-02-17 17:50:06 +0900216 auto p = vars->emplace(name, var);
Shinichiro Hamajicf0cd682015-06-18 16:18:13 +0900217 iter_ = p.first;
218 if (!p.second) {
219 orig_ = iter_->second;
220 iter_->second = var;
221 }
222}
223
224ScopedVar::~ScopedVar() {
225 if (orig_) {
226 iter_->second = orig_;
227 } else {
228 vars_->erase(iter_);
229 }
230}