30 :
Parser(state, file_reader),
31 options_(options), quiet_(false) {
62 if (!
ParseLet(&name, &let_value, err))
67 if (name ==
"ninja_required_version")
105 return lexer_.
Error(
"duplicate pool '" + name +
"'", err);
115 if (key ==
"depth") {
117 depth = atol(depth_string.c_str());
121 return lexer_.
Error(
"unexpected variable '" + key +
"'", err);
126 return lexer_.
Error(
"expected 'depth =' line", err);
142 return lexer_.
Error(
"duplicate rule '" + name +
"'", err);
157 return lexer_.
Error(
"unexpected variable '" + key +
"'", err);
161 if (rule->
bindings_[
"rspfile"].empty() !=
162 rule->
bindings_[
"rspfile_content"].empty()) {
163 return lexer_.
Error(
"rspfile and rspfile_content need to be " 164 "both specified", err);
168 return lexer_.
Error(
"expected 'command =' line", err);
176 return lexer_.
Error(
"expected variable name", err);
203 }
while (!eval.
empty());
212 vector<EvalString> ins, outs;
218 while (!out.
empty()) {
228 int implicit_outs = 0;
249 return lexer_.
Error(
"expected build command name", err);
253 return lexer_.
Error(
"unknown build rule '" + rule_name +
"'", err);
299 while (has_indent_token) {
313 if (!pool_name.empty()) {
316 return lexer_.
Error(
"unknown pool name '" + pool_name +
"'", err);
320 edge->
outputs_.reserve(outs.size());
321 for (
size_t i = 0, e = outs.size(); i != e; ++i) {
322 string path = outs[i].Evaluate(env);
329 lexer_.
Error(
"multiple rules generate " + path +
" [-w dupbuild=err]",
334 Warning(
"multiple rules generate %s. " 335 "builds involving this target will not be correct; " 336 "continuing anyway [-w dupbuild=warn]",
339 if (e - i <= static_cast<size_t>(implicit_outs))
353 edge->
inputs_.reserve(ins.size());
354 for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
355 string path = i->Evaluate(env);
372 vector<Node*>::iterator new_end =
374 if (new_end != edge->
inputs_.end()) {
377 Warning(
"phony target '%s' names itself as an input; " 378 "ignoring [-w phonycycle=warn]",
379 out->
path().c_str());
388 if (!dyndep.empty()) {
394 vector<Node*>::iterator dgi =
396 if (dgi == edge->
inputs_.end()) {
397 return lexer_.
Error(
"dyndep '" + dyndep +
"' is not an input", err);
bool ParseEdge(std::string *err)
bool AddDefault(StringPiece path, std::string *error)
std::string Evaluate(Env *env) const
const Rule * LookupRuleCurrentScope(const std::string &rule_name)
bool CanonicalizePath(string *path, uint64_t *slash_bits, string *err)
Node * GetNode(StringPiece path, uint64_t slash_bits)
PhonyCycleAction phony_cycle_action_
void UnreadToken()
Rewind to the last read Token.
ManifestParser(State *state, FileReader *file_reader, ManifestParserOptions options=ManifestParserOptions())
Information about a node in the dependency graph: the file, whether it's dirty, mtime, etc.
bool Parse(const std::string &filename, const std::string &input, std::string *err)
Parse a file, given its contents as a string.
bool ParsePool(std::string *err)
Parse various statement types.
void AddIn(Edge *edge, StringPiece path, uint64_t slash_bits)
std::vector< Node * > outputs_
bool Load(const std::string &filename, std::string *err, Lexer *parent=NULL)
Load and parse a file.
bool PeekToken(Token token)
If the next token is token, read it and return true.
An edge in the dependency graph; links between Nodes using Rules.
bool ReadVarValue(EvalString *value, std::string *err)
Read the value side of a var = value line (complete with $escapes).
const std::string & path() const
void CheckNinjaVersion(const string &version)
Token ReadToken()
Read a Token from the Token enum.
Edge * AddEdge(const Rule *rule)
bool ParseLet(std::string *key, EvalString *val, std::string *err)
bool ReadPath(EvalString *path, std::string *err)
Read a path (complete with $escapes).
An Env which contains a mapping of variables to values as well as a pointer to a parent scope...
static bool IsReservedBinding(const std::string &var)
bool ParseRule(std::string *err)
void AddRule(const Rule *rule)
bool AddOut(Edge *edge, StringPiece path, uint64_t slash_bits)
void set_dyndep_pending(bool pending)
bool Error(const std::string &message, std::string *err)
Construct an error message with context.
void AddBinding(const std::string &key, const EvalString &val)
An invokable build command and associated metadata (description, etc.).
bool ParseFileInclude(bool new_scope, std::string *err)
Parse either a 'subninja' or 'include' line.
std::string DescribeLastError()
If the last token read was an ERROR token, provide more info or the empty string. ...
A pool for delayed edges.
bool ParseDefault(std::string *err)
FileReader * file_reader_
Pool * LookupPool(const std::string &pool_name)
const Rule * LookupRule(const std::string &rule_name)
std::vector< Node * > inputs_
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
bool maybe_phonycycle_diagnostic() const
void AddBinding(const std::string &key, const std::string &val)
static const char * TokenName(Token t)
Return a human-readable form of a token, used in error messages.
ManifestParserOptions options_
Global state (file status) for a single run.
bool ReadIdent(std::string *out)
Read a simple identifier (a rule or variable name).
unsigned long long uint64_t
std::vector< Edge * > edges_
All the edges of the graph.
A tokenized string that contains variable references.
void Warning(const char *msg,...)
Log a warning message.
DupeEdgeAction dupe_edge_action_
std::string GetUnescapedDyndep() const
Like GetBinding("dyndep"), but without shell escaping.
void Start(StringPiece filename, StringPiece input)
Start parsing some input.
bool ExpectToken(Lexer::Token expected, std::string *err)
If the next token is not expected, produce an error string saying "expected foo, got bar"...
Interface for reading files from disk.