diff options
author | Alexei Svitkine <asvitkine@google.com> | 2011-04-26 18:49:49 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2011-04-26 18:49:49 (GMT) |
commit | 2f6ac73dad3806e771761af3a58d43d434337a4b (patch) | |
tree | de9266a1e7a635f66299a2847c6c66d894ad6637 /src/parsers.cc | |
parent | 5c192cda0788faeed93b3ba03a6830ed43762b24 (diff) | |
download | Ninja-2f6ac73dad3806e771761af3a58d43d434337a4b.zip Ninja-2f6ac73dad3806e771761af3a58d43d434337a4b.tar.gz Ninja-2f6ac73dad3806e771761af3a58d43d434337a4b.tar.bz2 |
include location of error in parse error messages in EvalEnv strings
E.g. when parsing "foo = ${bar", point at the correct location of
the missing curly brace.
Diffstat (limited to 'src/parsers.cc')
-rw-r--r-- | src/parsers.cc | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/parsers.cc b/src/parsers.cc index b9c1190..82b7111 100644 --- a/src/parsers.cc +++ b/src/parsers.cc @@ -52,7 +52,7 @@ void Tokenizer::Start(const char* start, const char* end) { bool Tokenizer::Error(const string& message, string* err) { char buf[1024]; - sprintf(buf, "line %d, col %d: %s", + snprintf(buf, sizeof(buf), "line %d, col %d: %s", line_number_, (int)(token_.pos_ - cur_line_) + 1, message.c_str()); @@ -123,7 +123,7 @@ bool Tokenizer::ReadIdent(string* out) { return true; } -bool Tokenizer::ReadToNewline(string* text, string* err) { +bool Tokenizer::ReadToNewline(string *text, string* err, size_t max_length) { // XXX token_.clear(); while (cur_ < end_ && *cur_ != '\n') { if (*cur_ == '\\') { @@ -149,6 +149,10 @@ bool Tokenizer::ReadToNewline(string* text, string* err) { text->push_back(*cur_); ++cur_; } + if (text->size() >= max_length) { + token_.pos_ = cur_; + return false; + } } return Newline(err); } @@ -367,6 +371,10 @@ bool ManifestParser::ParseLet(string* name, string* value, bool expand, if (!tokenizer_.ExpectToken(Token::EQUALS, err)) return false; + // Backup the tokenizer state prior to consuming the line, for reporting + // the source location in case of a parse error later. + Tokenizer tokenizer_backup = tokenizer_; + // XXX should we tokenize here? it means we'll need to understand // command syntax, though... if (!tokenizer_.ReadToNewline(value, err)) @@ -375,8 +383,14 @@ bool ManifestParser::ParseLet(string* name, string* value, bool expand, if (expand) { EvalString eval; string eval_err; - if (!eval.Parse(*value, &eval_err)) - return tokenizer_.Error(eval_err, err); + size_t err_index; + if (!eval.Parse(*value, &eval_err, &err_index)) { + string temp; + // Advance the saved tokenizer state up to the error index to report the + // error at the correct source location. + tokenizer_backup.ReadToNewline(&temp, err, err_index); + return tokenizer_backup.Error(eval_err, err); + } *value = eval.Evaluate(env_); } |