blob: e0f5be14efe267874a7441696e118a789fb500d9 [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 Hamaji645cca72015-09-24 17:04:21 +090017#include "expr.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090018
19#include <vector>
20
21#include "eval.h"
22#include "func.h"
23#include "log.h"
24#include "stringprintf.h"
25#include "strutil.h"
26#include "var.h"
27
Dan Willemsen3ce083f2017-10-11 22:17:48 -070028Evaluable::Evaluable() {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090029
Dan Willemsen3ce083f2017-10-11 22:17:48 -070030Evaluable::~Evaluable() {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090031
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +090032string Evaluable::Eval(Evaluator* ev) const {
33 string s;
34 Eval(ev, &s);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090035 return s;
36}
37
Dan Willemsen3ce083f2017-10-11 22:17:48 -070038Value::Value() {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090039
Dan Willemsen3ce083f2017-10-11 22:17:48 -070040Value::~Value() {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090041
Dan Willemsenee57a3f2018-11-05 16:18:44 -080042string Value::DebugString(const Value* v) {
Sasha Smundak8174f9b2018-08-13 11:07:30 -070043 return v ? NoLineBreak(v->DebugString_()) : "(null)";
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090044}
45
46class Literal : public Value {
47 public:
Dan Willemsen3ce083f2017-10-11 22:17:48 -070048 explicit Literal(StringPiece s) : s_(s) {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090049
50 StringPiece val() const { return s_; }
51
Dan Willemsen36e57292017-10-09 11:23:32 -070052 virtual void Eval(Evaluator* ev, string* s) const override {
53 ev->CheckStack();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090054 s->append(s_.begin(), s_.end());
55 }
56
Shinichiro Hamaji4b351ab2016-02-12 19:42:30 +090057 virtual bool IsLiteral() const override { return true; }
Shinichiro Hamaji71f58132016-02-22 16:20:27 +090058 virtual StringPiece GetLiteralValueUnsafe() const override { return s_; }
Shinichiro Hamaji347e06f2016-01-05 14:41:53 +090059
Dan Willemsen3ce083f2017-10-11 22:17:48 -070060 virtual string DebugString_() const override { return s_.as_string(); }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090061
62 private:
63 StringPiece s_;
64};
65
Sasha Smundakae1d58c2018-08-22 09:39:42 -070066class ValueList : public Value {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090067 public:
Sasha Smundakae1d58c2018-08-22 09:39:42 -070068 ValueList() {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090069
Dan Willemsenee57a3f2018-11-05 16:18:44 -080070 ValueList(Value* v1, Value* v2, Value* v3) : ValueList() {
Sasha Smundakae1d58c2018-08-22 09:39:42 -070071 vals_.reserve(3);
72 vals_.push_back(v1);
73 vals_.push_back(v2);
74 vals_.push_back(v3);
75 }
76
Dan Willemsenee57a3f2018-11-05 16:18:44 -080077 ValueList(Value* v1, Value* v2) : ValueList() {
Sasha Smundakae1d58c2018-08-22 09:39:42 -070078 vals_.reserve(2);
79 vals_.push_back(v1);
80 vals_.push_back(v2);
81 }
82
Dan Willemsenee57a3f2018-11-05 16:18:44 -080083 ValueList(vector<Value*>* values) : ValueList() {
Sasha Smundakae1d58c2018-08-22 09:39:42 -070084 values->shrink_to_fit();
85 values->swap(vals_);
86 }
87
Sasha Smundakae1d58c2018-08-22 09:39:42 -070088 virtual ~ValueList() {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090089 for (Value* v : vals_) {
90 delete v;
91 }
92 }
93
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090094 virtual void Eval(Evaluator* ev, string* s) const override {
Dan Willemsen36e57292017-10-09 11:23:32 -070095 ev->CheckStack();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090096 for (Value* v : vals_) {
97 v->Eval(ev, s);
98 }
99 }
100
101 virtual string DebugString_() const override {
102 string r;
103 for (Value* v : vals_) {
104 if (r.empty()) {
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700105 r += "ValueList(";
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900106 } else {
107 r += ", ";
108 }
Sasha Smundak8174f9b2018-08-13 11:07:30 -0700109 r += DebugString(v);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900110 }
Shinichiro Hamajibaf2c382015-07-07 14:53:02 +0900111 if (!r.empty())
112 r += ")";
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900113 return r;
114 }
115
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900116 private:
117 vector<Value*> vals_;
118};
119
Shinichiro Hamaji65489db2015-06-29 20:44:26 +0900120class SymRef : public Value {
121 public:
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700122 explicit SymRef(Symbol n) : name_(n) {}
123 virtual ~SymRef() {}
Shinichiro Hamaji65489db2015-06-29 20:44:26 +0900124
Shinichiro Hamaji65489db2015-06-29 20:44:26 +0900125 virtual void Eval(Evaluator* ev, string* s) const override {
Dan Willemsen36e57292017-10-09 11:23:32 -0700126 ev->CheckStack();
Shinichiro Hamaji65489db2015-06-29 20:44:26 +0900127 Var* v = ev->LookupVar(name_);
Dan Willemsen276e96a2017-10-03 14:24:48 -0700128 v->Used(ev, name_);
Shinichiro Hamaji65489db2015-06-29 20:44:26 +0900129 v->Eval(ev, s);
130 }
131
132 virtual string DebugString_() const override {
133 return StringPrintf("SymRef(%s)", name_.c_str());
134 }
135
136 private:
137 Symbol name_;
138};
139
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900140class VarRef : public Value {
141 public:
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700142 explicit VarRef(Value* n) : name_(n) {}
143 virtual ~VarRef() { delete name_; }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900144
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900145 virtual void Eval(Evaluator* ev, string* s) const override {
Dan Willemsen36e57292017-10-09 11:23:32 -0700146 ev->CheckStack();
Shinichiro Hamaji28da2372015-11-30 19:03:53 +0900147 ev->IncrementEvalDepth();
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900148 const string&& name = name_->Eval(ev);
Shinichiro Hamaji28da2372015-11-30 19:03:53 +0900149 ev->DecrementEvalDepth();
Dan Willemsen276e96a2017-10-03 14:24:48 -0700150 Symbol sym = Intern(name);
151 Var* v = ev->LookupVar(sym);
152 v->Used(ev, sym);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900153 v->Eval(ev, s);
154 }
155
156 virtual string DebugString_() const override {
Sasha Smundak8174f9b2018-08-13 11:07:30 -0700157 return StringPrintf("VarRef(%s)", Value::DebugString(name_).c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900158 }
159
160 private:
161 Value* name_;
162};
163
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900164class VarSubst : public Value {
165 public:
166 explicit VarSubst(Value* n, Value* p, Value* s)
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700167 : name_(n), pat_(p), subst_(s) {}
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900168 virtual ~VarSubst() {
169 delete name_;
170 delete pat_;
171 delete subst_;
172 }
173
174 virtual void Eval(Evaluator* ev, string* s) const override {
Dan Willemsen36e57292017-10-09 11:23:32 -0700175 ev->CheckStack();
Shinichiro Hamaji28da2372015-11-30 19:03:53 +0900176 ev->IncrementEvalDepth();
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900177 const string&& name = name_->Eval(ev);
Dan Willemsen276e96a2017-10-03 14:24:48 -0700178 Symbol sym = Intern(name);
179 Var* v = ev->LookupVar(sym);
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900180 const string&& pat_str = pat_->Eval(ev);
181 const string&& subst = subst_->Eval(ev);
Shinichiro Hamaji28da2372015-11-30 19:03:53 +0900182 ev->DecrementEvalDepth();
Dan Willemsen276e96a2017-10-03 14:24:48 -0700183 v->Used(ev, sym);
Shinichiro Hamaji28da2372015-11-30 19:03:53 +0900184 const string&& value = v->Eval(ev);
Shinichiro Hamaji37591ce2015-06-16 19:36:05 +0900185 WordWriter ww(s);
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900186 Pattern pat(pat_str);
187 for (StringPiece tok : WordScanner(value)) {
Shinichiro Hamaji37591ce2015-06-16 19:36:05 +0900188 ww.MaybeAddWhitespace();
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900189 pat.AppendSubstRef(tok, subst, s);
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900190 }
191 }
192
193 virtual string DebugString_() const override {
Sasha Smundak8174f9b2018-08-13 11:07:30 -0700194 return StringPrintf("VarSubst(%s:%s=%s)", Value::DebugString(name_).c_str(),
195 Value::DebugString(pat_).c_str(),
196 Value::DebugString(subst_).c_str());
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900197 }
198
199 private:
200 Value* name_;
201 Value* pat_;
202 Value* subst_;
203};
204
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900205class Func : public Value {
206 public:
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700207 explicit Func(FuncInfo* fi) : fi_(fi) {}
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900208
Shinichiro Hamajid0e188e2015-06-16 18:53:01 +0900209 ~Func() {
210 for (Value* a : args_)
211 delete a;
212 }
213
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900214 virtual void Eval(Evaluator* ev, string* s) const override {
Dan Willemsen36e57292017-10-09 11:23:32 -0700215 ev->CheckStack();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900216 LOG("Invoke func %s(%s)", name(), JoinValues(args_, ",").c_str());
Shinichiro Hamaji28da2372015-11-30 19:03:53 +0900217 ev->IncrementEvalDepth();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900218 fi_->func(args_, ev, s);
Shinichiro Hamaji28da2372015-11-30 19:03:53 +0900219 ev->DecrementEvalDepth();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900220 }
221
222 virtual string DebugString_() const override {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700223 return StringPrintf("Func(%s %s)", fi_->name,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900224 JoinValues(args_, ",").c_str());
225 }
226
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700227 void AddArg(Value* v) { args_.push_back(v); }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900228
229 const char* name() const { return fi_->name; }
230 int arity() const { return fi_->arity; }
Shinichiro Hamajifead3b72015-06-18 15:31:15 +0900231 int min_arity() const { return fi_->min_arity; }
232 bool trim_space() const { return fi_->trim_space; }
233 bool trim_right_space_1st() const { return fi_->trim_right_space_1st; }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900234
235 private:
236 FuncInfo* fi_;
237 vector<Value*> args_;
238};
239
240static char CloseParen(char c) {
241 switch (c) {
242 case '(':
243 return ')';
244 case '{':
245 return '}';
246 }
247 return 0;
248}
249
250static size_t SkipSpaces(StringPiece s, const char* terms) {
251 for (size_t i = 0; i < s.size(); i++) {
252 char c = s[i];
Shinichiro Hamaji64cf8912015-06-26 09:25:19 +0900253 if (strchr(terms, c))
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900254 return i;
Shinichiro Hamaji64cf8912015-06-26 09:25:19 +0900255 if (!isspace(c)) {
256 if (c != '\\')
257 return i;
258 char n = s.get(i + 1);
259 if (n != '\r' && n != '\n')
260 return i;
261 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900262 }
263 return s.size();
264}
265
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700266Value* Value::NewExpr(Value* v1, Value* v2) {
267 return new ValueList(v1, v2);
268}
269
270Value* Value::NewExpr(Value* v1, Value* v2, Value* v3) {
271 return new ValueList(v1, v2, v3);
272}
273
Dan Willemsenee57a3f2018-11-05 16:18:44 -0800274Value* Value::NewExpr(vector<Value*>* values) {
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700275 if (values->size() == 1) {
Dan Willemsenee57a3f2018-11-05 16:18:44 -0800276 Value* v = (*values)[0];
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700277 values->clear();
278 return v;
279 }
280 return new ValueList(values);
281}
282
283Value* Value::NewLiteral(StringPiece s) {
284 return new Literal(s);
285}
286
Shinichiro Hamaji4d77b842015-06-27 06:10:18 +0900287bool ShouldHandleComments(ParseExprOpt opt) {
288 return opt != ParseExprOpt::DEFINE && opt != ParseExprOpt::COMMAND;
289}
290
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900291void ParseFunc(const Loc& loc,
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700292 Func* f,
293 StringPiece s,
294 size_t i,
295 char* terms,
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900296 size_t* index_out) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900297 terms[1] = ',';
298 terms[2] = '\0';
299 i += SkipSpaces(s.substr(i), terms);
300 if (i == s.size()) {
301 *index_out = i;
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900302 return;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900303 }
304
305 int nargs = 1;
306 while (true) {
307 if (f->arity() && nargs >= f->arity()) {
308 terms[1] = '\0'; // Drop ','.
309 }
310
Shinichiro Hamajifead3b72015-06-18 15:31:15 +0900311 if (f->trim_space()) {
Shinichiro Hamajic8b4b1c2015-07-07 14:57:53 +0900312 for (; i < s.size(); i++) {
313 if (isspace(s[i]))
314 continue;
315 if (s[i] == '\\') {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700316 char c = s.get(i + 1);
Shinichiro Hamajic8b4b1c2015-07-07 14:57:53 +0900317 if (c == '\r' || c == '\n')
318 continue;
319 }
320 break;
321 }
Shinichiro Hamajifead3b72015-06-18 15:31:15 +0900322 }
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700323 const bool trim_right_space =
324 (f->trim_space() || (nargs == 1 && f->trim_right_space_1st()));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900325 size_t n;
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700326 Value* v = ParseExprImpl(loc, s.substr(i), terms, ParseExprOpt::FUNC, &n,
327 trim_right_space);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900328 // TODO: concatLine???
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900329 f->AddArg(v);
330 i += n;
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900331 if (i == s.size()) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700332 ERROR_LOC(loc,
333 "*** unterminated call to function '%s': "
Dan Willemsene41c7552017-02-22 14:31:16 -0800334 "missing '%c'.",
335 f->name(), terms[0]);
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900336 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900337 nargs++;
338 if (s[i] == terms[0]) {
339 i++;
340 break;
341 }
342 i++; // Should be ','.
343 if (i == s.size())
344 break;
345 }
346
Shinichiro Hamajifead3b72015-06-18 15:31:15 +0900347 if (nargs <= f->min_arity()) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700348 ERROR_LOC(loc,
349 "*** insufficient number of arguments (%d) to function `%s'.",
Dan Willemsene41c7552017-02-22 14:31:16 -0800350 nargs - 1, f->name());
Shinichiro Hamaji81b2d0f2015-06-16 19:25:35 +0900351 }
352
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900353 *index_out = i;
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900354 return;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900355}
356
Shinichiro Hamaji36b326f2015-06-26 08:56:13 +0900357Value* ParseDollar(const Loc& loc, StringPiece s, size_t* index_out) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900358 CHECK(s.size() >= 2);
359 CHECK(s[0] == '$');
360 CHECK(s[1] != '$');
361
362 char cp = CloseParen(s[1]);
363 if (cp == 0) {
364 *index_out = 2;
Shinichiro Hamaji65489db2015-06-29 20:44:26 +0900365 return new SymRef(Intern(s.substr(1, 1)));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900366 }
367
368 char terms[] = {cp, ':', ' ', 0};
369 for (size_t i = 2;;) {
370 size_t n;
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700371 Value* vname =
372 ParseExprImpl(loc, s.substr(i), terms, ParseExprOpt::NORMAL, &n);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900373 i += n;
374 if (s[i] == cp) {
375 *index_out = i + 1;
Shinichiro Hamaji347e06f2016-01-05 14:41:53 +0900376 if (vname->IsLiteral()) {
377 Literal* lit = static_cast<Literal*>(vname);
Shinichiro Hamaji82e20092015-11-17 15:18:28 +0900378 Symbol sym = Intern(lit->val());
379 if (g_flags.enable_kati_warnings) {
380 size_t found = sym.str().find_first_of(" ({");
381 if (found != string::npos) {
Dan Willemsene41c7552017-02-22 14:31:16 -0800382 KATI_WARN_LOC(loc, "*warning*: variable lookup with '%c': %.*s",
383 sym.str()[found], SPF(s));
Shinichiro Hamaji82e20092015-11-17 15:18:28 +0900384 }
385 }
386 Value* r = new SymRef(sym);
Shinichiro Hamaji65489db2015-06-29 20:44:26 +0900387 delete lit;
388 return r;
389 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900390 return new VarRef(vname);
391 }
392
Shinichiro Hamajia0315fc2015-06-26 08:15:55 +0900393 if (s[i] == ' ' || s[i] == '\\') {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900394 // ${func ...}
Shinichiro Hamaji347e06f2016-01-05 14:41:53 +0900395 if (vname->IsLiteral()) {
396 Literal* lit = static_cast<Literal*>(vname);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900397 if (FuncInfo* fi = GetFuncInfo(lit->val())) {
Shinichiro Hamajid0e188e2015-06-16 18:53:01 +0900398 delete lit;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900399 Func* func = new Func(fi);
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700400 ParseFunc(loc, func, s, i + 1, terms, index_out);
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900401 return func;
Shinichiro Hamaji82e20092015-11-17 15:18:28 +0900402 } else {
Dan Willemsene41c7552017-02-22 14:31:16 -0800403 KATI_WARN_LOC(loc, "*warning*: unknown make function '%.*s': %.*s",
404 SPF(lit->val()), SPF(s));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900405 }
406 }
407
408 // Not a function. Drop ' ' from |terms| and parse it
409 // again. This is inefficient, but this code path should be
410 // rarely used.
411 delete vname;
412 terms[2] = 0;
413 i = 2;
414 continue;
415 }
416
417 if (s[i] == ':') {
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900418 terms[2] = '\0';
419 terms[1] = '=';
420 size_t n;
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700421 Value* pat =
422 ParseExprImpl(loc, s.substr(i + 1), terms, ParseExprOpt::NORMAL, &n);
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900423 i += 1 + n;
424 if (s[i] == cp) {
Shinichiro Hamajif72e0242015-06-26 00:38:27 +0900425 *index_out = i + 1;
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700426 return new VarRef(Value::NewExpr(vname, new Literal(":"), pat));
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900427 }
428
429 terms[1] = '\0';
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700430 Value* subst =
431 ParseExprImpl(loc, s.substr(i + 1), terms, ParseExprOpt::NORMAL, &n);
Shinichiro Hamaji02fc55b2015-06-16 17:19:07 +0900432 i += 1 + n;
Shinichiro Hamajif72e0242015-06-26 00:38:27 +0900433 *index_out = i + 1;
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700434 return new VarSubst(vname, pat, subst);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900435 }
436
Shinichiro Hamaji0f7af702015-07-05 02:00:18 +0900437 // GNU make accepts expressions like $((). See unmatched_paren*.mk
438 // for detail.
Shinichiro Hamaji663a35b2015-07-05 01:50:41 +0900439 size_t found = s.find(cp);
Shinichiro Hamaji0f7af702015-07-05 02:00:18 +0900440 if (found != string::npos) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700441 KATI_WARN_LOC(loc, "*warning*: unmatched parentheses: %.*s", SPF(s));
Shinichiro Hamaji0f7af702015-07-05 02:00:18 +0900442 *index_out = s.size();
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700443 return new SymRef(Intern(s.substr(2, found - 2)));
Shinichiro Hamaji0f7af702015-07-05 02:00:18 +0900444 }
Dan Willemsene41c7552017-02-22 14:31:16 -0800445 ERROR_LOC(loc, "*** unterminated variable reference.");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900446 }
447}
448
Shinichiro Hamaji36b326f2015-06-26 08:56:13 +0900449Value* ParseExprImpl(const Loc& loc,
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700450 StringPiece s,
451 const char* terms,
452 ParseExprOpt opt,
453 size_t* index_out,
454 bool trim_right_space) {
Shinichiro Hamaji47898a82015-06-19 16:45:33 +0900455 if (s.get(s.size() - 1) == '\r')
456 s.remove_suffix(1);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900457
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900458 size_t b = 0;
459 char save_paren = 0;
460 int paren_depth = 0;
461 size_t i;
Dan Willemsenee57a3f2018-11-05 16:18:44 -0800462 vector<Value*> list;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900463 for (i = 0; i < s.size(); i++) {
464 char c = s[i];
Shinichiro Hamaji170e8b32015-09-15 15:36:57 +0900465 if (terms && strchr(terms, c) && !save_paren) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900466 break;
467 }
468
469 // Handle a comment.
Shinichiro Hamaji4d77b842015-06-27 06:10:18 +0900470 if (!terms && c == '#' && ShouldHandleComments(opt)) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900471 if (i > b)
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700472 list.push_back(new Literal(s.substr(b, i - b)));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900473 bool was_backslash = false;
474 for (; i < s.size() && !(s[i] == '\n' && !was_backslash); i++) {
475 was_backslash = !was_backslash && s[i] == '\\';
476 }
477 *index_out = i;
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700478 return Value::NewExpr(&list);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900479 }
480
481 if (c == '$') {
482 if (i + 1 >= s.size()) {
483 break;
484 }
485
486 if (i > b)
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700487 list.push_back(new Literal(s.substr(b, i - b)));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900488
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700489 if (s[i + 1] == '$') {
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700490 list.push_back(new Literal(StringPiece("$")));
Shinichiro Hamajib8a2bb12015-06-26 09:04:57 +0900491 i += 1;
492 b = i + 1;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900493 continue;
494 }
495
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700496 if (terms && strchr(terms, s[i + 1])) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900497 *index_out = i + 1;
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700498 return Value::NewExpr(&list);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900499 }
500
501 size_t n;
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700502 list.push_back(ParseDollar(loc, s.substr(i), &n));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900503 i += n;
504 b = i;
505 i--;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900506 continue;
507 }
508
Shinichiro Hamaji4d77b842015-06-27 06:10:18 +0900509 if ((c == '(' || c == '{') && opt == ParseExprOpt::FUNC) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900510 char cp = CloseParen(c);
511 if (terms && terms[0] == cp) {
512 paren_depth++;
513 save_paren = cp;
514 terms++;
515 } else if (cp == save_paren) {
516 paren_depth++;
517 }
518 continue;
519 }
520
521 if (c == save_paren) {
522 paren_depth--;
523 if (paren_depth == 0) {
524 terms--;
525 save_paren = 0;
526 }
527 }
528
Shinichiro Hamaji66bd7bc2015-06-19 16:54:06 +0900529 if (c == '\\' && i + 1 < s.size() && opt != ParseExprOpt::COMMAND) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700530 char n = s[i + 1];
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900531 if (n == '\\') {
532 i++;
533 continue;
534 }
Shinichiro Hamaji4d77b842015-06-27 06:10:18 +0900535 if (n == '#' && ShouldHandleComments(opt)) {
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700536 list.push_back(new Literal(s.substr(b, i - b)));
Shinichiro Hamaji7fb82b02015-06-26 00:06:51 +0900537 i++;
538 b = i;
539 continue;
540 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900541 if (n == '\r' || n == '\n') {
Shinichiro Hamajia0315fc2015-06-26 08:15:55 +0900542 if (terms && strchr(terms, ' ')) {
543 break;
544 }
Shinichiro Hamaji47898a82015-06-19 16:45:33 +0900545 if (i > b) {
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700546 list.push_back(new Literal(TrimRightSpace(s.substr(b, i - b))));
Shinichiro Hamaji47898a82015-06-19 16:45:33 +0900547 }
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700548 list.push_back(new Literal(StringPiece(" ")));
Dan Willemsenae8fc802015-08-20 13:46:14 -0700549 // Skip the current escaped newline
550 i += 2;
Shinichiro Hamaji3e98b6b2016-06-07 14:35:41 +0900551 if (n == '\r' && s.get(i) == '\n')
552 i++;
Dan Willemsenae8fc802015-08-20 13:46:14 -0700553 // Then continue skipping escaped newlines, spaces, and tabs
554 for (; i < s.size(); i++) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700555 if (s[i] == '\\' && (s.get(i + 1) == '\r' || s.get(i + 1) == '\n')) {
Dan Willemsenae8fc802015-08-20 13:46:14 -0700556 i++;
557 continue;
558 }
559 if (s[i] != ' ' && s[i] != '\t') {
Shinichiro Hamaji8f464582015-06-24 20:41:46 +0900560 break;
561 }
562 }
563 b = i;
564 i--;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900565 }
566 }
567 }
568
Shinichiro Hamajid146f4c2015-06-17 17:51:24 +0900569 if (i > b) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700570 StringPiece rest = s.substr(b, i - b);
Shinichiro Hamajid146f4c2015-06-17 17:51:24 +0900571 if (trim_right_space)
572 rest = TrimRightSpace(rest);
573 if (!rest.empty())
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700574 list.push_back(new Literal(rest));
Shinichiro Hamajid146f4c2015-06-17 17:51:24 +0900575 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900576 *index_out = i;
Sasha Smundakae1d58c2018-08-22 09:39:42 -0700577 return Value::NewExpr(&list);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900578}
579
Shinichiro Hamaji36b326f2015-06-26 08:56:13 +0900580Value* ParseExpr(const Loc& loc, StringPiece s, ParseExprOpt opt) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900581 size_t n;
Shinichiro Hamaji36b326f2015-06-26 08:56:13 +0900582 return ParseExprImpl(loc, s, NULL, opt, &n);
Shinichiro Hamajid146f4c2015-06-17 17:51:24 +0900583}
584
Shinichiro Hamaji76ff9832015-06-18 17:11:22 +0900585string JoinValues(const vector<Value*>& vals, const char* sep) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900586 vector<string> val_strs;
587 for (Value* v : vals) {
Sasha Smundak8174f9b2018-08-13 11:07:30 -0700588 val_strs.push_back(Value::DebugString(v));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900589 }
590 return JoinStrings(val_strs, sep);
591}