33 :
Parser(state, file_reader),
40 lexer_.Start(filename, input);
65 if (!
ParseLet(&name, &let_value, err))
70 if (name ==
"ninja_required_version")
72 env_->AddBinding(name, value);
101 if (!
lexer_.ReadIdent(&name))
102 return lexer_.Error(
"expected pool name", err);
107 if (
state_->LookupPool(name) != NULL)
108 return lexer_.Error(
"duplicate pool '" + name +
"'", err);
118 if (key ==
"depth") {
120 depth = atoi(depth_string.c_str());
122 return lexer_.Error(
"invalid pool depth", err);
124 return lexer_.Error(
"unexpected variable '" + key +
"'", err);
129 return lexer_.Error(
"expected 'depth =' line", err);
138 if (!
lexer_.ReadIdent(&name))
139 return lexer_.Error(
"expected rule name", err);
144 if (
env_->LookupRuleCurrentScope(name) != NULL)
145 return lexer_.Error(
"duplicate rule '" + name +
"'", err);
147 auto rule = std::unique_ptr<Rule>(
new Rule(name));
156 rule->AddBinding(key, value);
160 return lexer_.Error(
"unexpected variable '" + key +
"'", err);
164 if (rule->bindings_[
"rspfile"].empty() !=
165 rule->bindings_[
"rspfile_content"].empty()) {
166 return lexer_.Error(
"rspfile and rspfile_content need to be "
167 "both specified", err);
170 if (rule->bindings_[
"command"].empty())
171 return lexer_.Error(
"expected 'command =' line", err);
173 env_->AddRule(std::move(rule));
178 if (!
lexer_.ReadIdent(key))
179 return lexer_.Error(
"expected variable name", err);
182 if (!
lexer_.ReadVarValue(value, err))
189 if (!
lexer_.ReadPath(&eval, err))
192 return lexer_.Error(
"expected target name", err);
197 return lexer_.Error(
"empty path", err);
200 std::string default_err;
201 if (!
state_->AddDefault(path, &default_err))
202 return lexer_.Error(default_err, err);
205 if (!
lexer_.ReadPath(&eval, err))
207 }
while (!eval.
empty());
219 if (!
lexer_.ReadPath(&out, err))
221 while (!out.
empty()) {
222 outs_.push_back(std::move(out));
225 if (!
lexer_.ReadPath(&out, err))
231 int implicit_outs = 0;
235 if (!
lexer_.ReadPath(&out, err))
239 outs_.push_back(std::move(out));
245 return lexer_.Error(
"expected path", err);
251 if (!
lexer_.ReadIdent(&rule_name))
252 return lexer_.Error(
"expected build command name", err);
254 const Rule* rule =
env_->LookupRule(rule_name);
256 return lexer_.Error(
"unknown build rule '" + rule_name +
"'", err);
261 if (!
lexer_.ReadPath(&in, err))
265 ins_.push_back(std::move(in));
273 if (!
lexer_.ReadPath(&in, err))
277 ins_.push_back(std::move(in));
287 if (!
lexer_.ReadPath(&in, err))
291 ins_.push_back(std::move(in));
300 if (!
lexer_.ReadPath(&validation, err))
302 if (validation.
empty())
314 while (has_indent_token) {
328 if (!pool_name.empty()) {
331 return lexer_.Error(
"unknown pool name '" + pool_name +
"'", err);
336 for (
size_t i = 0, e =
outs_.size(); i != e; ++i) {
337 string path =
outs_[i].Evaluate(env);
339 return lexer_.Error(
"empty path", err);
342 if (!
state_->AddOut(edge, path, slash_bits, err)) {
343 lexer_.Error(std::string(*err), err);
351 state_->edges_.pop_back();
358 for (vector<EvalString>::iterator i =
ins_.begin(); i !=
ins_.end(); ++i) {
359 string path = i->Evaluate(env);
361 return lexer_.Error(
"empty path", err);
364 state_->AddIn(edge, path, slash_bits);
370 for (std::vector<EvalString>::iterator v =
validations_.begin();
372 string path = v->Evaluate(env);
374 return lexer_.Error(
"empty path", err);
377 state_->AddValidation(edge, path, slash_bits);
387 vector<Node*>::iterator new_end =
389 if (new_end != edge->
inputs_.end()) {
392 Warning(
"phony target '%s' names itself as an input; "
393 "ignoring [-w phonycycle=warn]",
394 out->
path().c_str());
403 if (!dyndep.empty()) {
408 vector<Node*>::iterator dgi =
410 if (dgi == edge->
inputs_.end()) {
411 return lexer_.Error(
"dyndep '" + dyndep +
"' is not an input", err);
421 if (!
lexer_.ReadPath(&eval, err))
An Env which contains a mapping of variables to values as well as a pointer to a parent scope.
void AddBinding(const std::string &key, const std::string &val)
An edge in the dependency graph; links between Nodes using Rules.
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
bool maybe_phonycycle_diagnostic() const
std::string GetUnescapedDyndep() const
Like GetBinding("dyndep"), but without shell escaping.
std::vector< Node * > outputs_
std::vector< Node * > validations_
std::vector< Node * > inputs_
A tokenized string that contains variable references.
std::string Evaluate(Env *env) const
Interface for reading files from disk.
static const char * TokenName(Token t)
Return a human-readable form of a token, used in error messages.
bool ParseEdge(std::string *err)
std::unique_ptr< ManifestParser > subparser_
bool ParseRule(std::string *err)
bool Parse(const std::string &filename, const std::string &input, std::string *err)
Parse a file, given its contents as a string.
ManifestParserOptions options_
std::vector< EvalString > outs_
std::vector< EvalString > ins_
bool ParseDefault(std::string *err)
bool ParsePool(std::string *err)
Parse various statement types.
std::vector< EvalString > validations_
ManifestParser(State *state, FileReader *file_reader, ManifestParserOptions options=ManifestParserOptions())
bool ParseFileInclude(bool new_scope, std::string *err)
Parse either a 'subninja' or 'include' line.
bool ParseLet(std::string *key, EvalString *val, std::string *err)
Information about a node in the dependency graph: the file, whether it's dirty, mtime,...
const std::string & path() const
void set_dyndep_pending(bool pending)
bool generated_by_dep_loader() const
Indicates whether this node was generated from a depfile or dyndep file, instead of being a regular i...
FileReader * file_reader_
bool ExpectToken(Lexer::Token expected, std::string *err)
If the next token is not expected, produce an error string saying "expected foo, got bar".
Parser(State *state, FileReader *file_reader)
A pool for delayed edges.
An invocable build command and associated metadata (description, etc.).
static bool IsReservedBinding(const std::string &var)
Global state (file status) for a single run.
void Warning(const char *msg, va_list ap)
void CanonicalizePath(string *path, uint64_t *slash_bits)
void CheckNinjaVersion(const string &version)
unsigned long long uint64_t