Coverage Report

Created: 2025-11-11 08:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ninja/src/eval_env.cc
Line
Count
Source
1
// Copyright 2011 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
#include <assert.h>
16
17
#include "eval_env.h"
18
19
using namespace std;
20
21
638k
string BindingEnv::LookupVariable(const string& var) {
22
638k
  map<string, string>::iterator i = bindings_.find(var);
23
638k
  if (i != bindings_.end())
24
530k
    return i->second;
25
107k
  if (parent_)
26
34.7k
    return parent_->LookupVariable(var);
27
73.1k
  return "";
28
107k
}
29
30
242k
void BindingEnv::AddBinding(const string& key, const string& val) {
31
242k
  bindings_[key] = val;
32
242k
}
33
34
2.83k
void BindingEnv::AddRule(std::unique_ptr<const Rule> rule) {
35
2.83k
  assert(LookupRuleCurrentScope(rule->name()) == NULL);
36
2.83k
  rules_[rule->name()] = std::move(rule);
37
2.83k
}
38
39
5.03k
const Rule* BindingEnv::LookupRuleCurrentScope(const string& rule_name) {
40
5.03k
  auto i = rules_.find(rule_name);
41
5.03k
  if (i == rules_.end())
42
5.02k
    return NULL;
43
8
  return i->second.get();
44
5.03k
}
45
46
161k
const Rule* BindingEnv::LookupRule(const string& rule_name) {
47
161k
  auto i = rules_.find(rule_name);
48
161k
  if (i != rules_.end())
49
161k
    return i->second.get();
50
24
  if (parent_)
51
0
    return parent_->LookupRule(rule_name);
52
24
  return NULL;
53
24
}
54
55
8.52k
void Rule::AddBinding(const string& key, const EvalString& val) {
56
8.52k
  bindings_[key] = val;
57
8.52k
}
58
59
493k
const EvalString* Rule::GetBinding(const string& key) const {
60
493k
  Bindings::const_iterator i = bindings_.find(key);
61
493k
  if (i == bindings_.end())
62
493k
    return NULL;
63
729
  return &i->second;
64
493k
}
65
66
720
std::unique_ptr<Rule> Rule::Phony() {
67
720
  auto rule = std::unique_ptr<Rule>(new Rule("phony"));
68
720
  rule->phony_ = true;
69
720
  return rule;
70
720
}
71
72
161k
bool Rule::IsPhony() const {
73
161k
  return phony_;
74
161k
}
75
76
// static
77
8.53k
bool Rule::IsReservedBinding(const string& var) {
78
8.53k
  return var == "command" ||
79
4.73k
      var == "depfile" ||
80
4.28k
      var == "dyndep" ||
81
3.88k
      var == "description" ||
82
3.61k
      var == "deps" ||
83
3.09k
      var == "generator" ||
84
2.58k
      var == "pool" ||
85
1.69k
      var == "restat" ||
86
1.33k
      var == "rspfile" ||
87
1.03k
      var == "rspfile_content" ||
88
555
      var == "msvc_deps_prefix";
89
8.53k
}
90
91
0
const map<string, std::unique_ptr<const Rule>>& BindingEnv::GetRules() const {
92
0
  return rules_;
93
0
}
94
95
string BindingEnv::LookupWithFallback(const string& var,
96
                                      const EvalString* eval,
97
493k
                                      Env* env) {
98
493k
  map<string, string>::iterator i = bindings_.find(var);
99
493k
  if (i != bindings_.end())
100
1.46k
    return i->second;
101
102
492k
  if (eval)
103
729
    return eval->Evaluate(env);
104
105
491k
  if (parent_)
106
317
    return parent_->LookupVariable(var);
107
108
491k
  return "";
109
491k
}
110
111
1.78M
string EvalString::Evaluate(Env* env) const {
112
1.78M
  if (parsed_.empty()) {
113
1.22M
    return single_token_;
114
1.22M
  }
115
116
560k
  string result;
117
1.75M
  for (TokenList::const_iterator i = parsed_.begin(); i != parsed_.end(); ++i) {
118
1.19M
    if (i->second == RAW)
119
420k
      result.append(i->first);
120
776k
    else
121
776k
      result.append(env->LookupVariable(i->first));
122
1.19M
  }
123
560k
  return result;
124
1.78M
}
125
126
2.19M
void EvalString::AddText(StringPiece text) {
127
2.19M
  if (parsed_.empty()) {
128
1.72M
    single_token_.append(text.begin(), text.end());
129
1.72M
  } else if (!parsed_.empty() && parsed_.back().second == RAW) {
130
235k
    parsed_.back().first.append(text.begin(), text.end());
131
237k
  } else {
132
237k
    parsed_.push_back(std::make_pair(text.AsString(), RAW));
133
237k
  }
134
2.19M
}
135
136
852k
void EvalString::AddSpecial(StringPiece text) {
137
852k
  if (parsed_.empty() && !single_token_.empty()) {
138
    // Going from one to two tokens, so we can no longer apply
139
    // our single_token_ optimization and need to push everything
140
    // onto the vector.
141
237k
    parsed_.push_back(std::make_pair(std::move(single_token_), RAW));
142
237k
  }
143
852k
  parsed_.push_back(std::make_pair(text.AsString(), SPECIAL));
144
852k
}
145
146
0
string EvalString::Serialize() const {
147
0
  string result;
148
0
  if (parsed_.empty() && !single_token_.empty()) {
149
0
    result.append("[");
150
0
    result.append(single_token_);
151
0
    result.append("]");
152
0
  } else {
153
0
    for (const auto& pair : parsed_) {
154
0
      result.append("[");
155
0
      if (pair.second == SPECIAL)
156
0
        result.append("$");
157
0
      result.append(pair.first.begin(), pair.first.end());
158
0
      result.append("]");
159
0
    }
160
0
  }
161
0
  return result;
162
0
}
163
164
0
string EvalString::Unparse() const {
165
0
  string result;
166
0
  if (parsed_.empty() && !single_token_.empty()) {
167
0
    result.append(single_token_.begin(), single_token_.end());
168
0
  } else {
169
0
    for (TokenList::const_iterator i = parsed_.begin();
170
0
         i != parsed_.end(); ++i) {
171
0
      bool special = (i->second == SPECIAL);
172
0
      if (special)
173
0
        result.append("${");
174
0
      result.append(i->first.begin(), i->first.end());
175
0
      if (special)
176
0
        result.append("}");
177
0
    }
178
0
  }
179
0
  return result;
180
0
}