diff options
author | Peter Kuemmel <syntheticpp@gmx.net> | 2012-01-29 13:26:24 (GMT) |
---|---|---|
committer | Peter Kuemmel <syntheticpp@gmx.net> | 2012-01-29 13:26:24 (GMT) |
commit | 2e481086ad7337bb868327f12ffd317dc5143a3e (patch) | |
tree | 970d5c7fb9207ec96beff9d9fdfcf60c60a06e0d /src | |
parent | 88c9491f515f7ba479b5334ef834743fed539730 (diff) | |
download | Ninja-2e481086ad7337bb868327f12ffd317dc5143a3e.zip Ninja-2e481086ad7337bb868327f12ffd317dc5143a3e.tar.gz Ninja-2e481086ad7337bb868327f12ffd317dc5143a3e.tar.bz2 |
parse $:
'$:' is a valid string now, it expands to ':'
update error messages and show a hint when something went wrong.
Diffstat (limited to 'src')
-rw-r--r-- | src/lexer.cc | 20 | ||||
-rw-r--r-- | src/lexer.h | 4 | ||||
-rw-r--r-- | src/lexer.in.cc | 20 | ||||
-rw-r--r-- | src/parsers.cc | 1 | ||||
-rw-r--r-- | src/parsers_test.cc | 37 |
5 files changed, 78 insertions, 4 deletions
diff --git a/src/lexer.cc b/src/lexer.cc index a1bedf5..9e4392c 100644 --- a/src/lexer.cc +++ b/src/lexer.cc @@ -90,6 +90,26 @@ const char* Lexer::TokenName(Token t) { return NULL; // not reached } +const char* Lexer::TokenErrorHint(Token t) { + switch (t) { + case ERROR: return ""; + case BUILD: return ""; + case COLON: return " ($ also escapes ':')"; + case DEFAULT: return ""; + case EQUALS: return ""; + case IDENT: return ""; + case INCLUDE: return ""; + case INDENT: return ""; + case NEWLINE: return ""; + case PIPE2: return ""; + case PIPE: return ""; + case RULE: return ""; + case SUBNINJA: return ""; + case TEOF: return ""; + } + return ""; +} + void Lexer::UnreadToken() { ofs_ = last_token_; } diff --git a/src/lexer.h b/src/lexer.h index c872b98..75c1b2f 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -46,6 +46,10 @@ struct Lexer { /// Return a human-readable form of a token, used in error messages. static const char* TokenName(Token t); + + /// Return a human-readable token hint, used in error messages. + static const char* TokenErrorHint(Token t); + /// Start parsing some input. void Start(StringPiece filename, StringPiece input); diff --git a/src/lexer.in.cc b/src/lexer.in.cc index 9caaa36..28a5bdf 100644 --- a/src/lexer.in.cc +++ b/src/lexer.in.cc @@ -89,6 +89,26 @@ const char* Lexer::TokenName(Token t) { return NULL; // not reached } +const char* Lexer::TokenErrorHint(Token t) { + switch (t) { + case ERROR: return ""; + case BUILD: return ""; + case COLON: return " ($ also escapes ':')"; + case DEFAULT: return ""; + case EQUALS: return ""; + case IDENT: return ""; + case INCLUDE: return ""; + case INDENT: return ""; + case NEWLINE: return ""; + case PIPE2: return ""; + case PIPE: return ""; + case RULE: return ""; + case SUBNINJA: return ""; + case TEOF: return ""; + } + return ""; +} + void Lexer::UnreadToken() { ofs_ = last_token_; } diff --git a/src/parsers.cc b/src/parsers.cc index c1badd8..5d347b2 100644 --- a/src/parsers.cc +++ b/src/parsers.cc @@ -313,6 +313,7 @@ bool ManifestParser::ExpectToken(Lexer::Token expected, string* err) { if (token != expected) { string message = string("expected ") + Lexer::TokenName(expected); message += string(", got ") + Lexer::TokenName(token); + message += Lexer::TokenErrorHint(expected); return lexer_.Error(message, err); } return true; diff --git a/src/parsers_test.cc b/src/parsers_test.cc index f3ac517..2a30a83 100644 --- a/src/parsers_test.cc +++ b/src/parsers_test.cc @@ -377,14 +377,30 @@ TEST_F(ParserTest, Errors) { ManifestParser parser(&state, NULL); string err; EXPECT_FALSE(parser.ParseTest("rule cat\n" - " command = cat\nbuild $: cat foo\n", + " command = cat\n" + "build $.: cat foo\n", &err)); EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n" - "build $: cat foo\n" + "build $.: cat foo\n" " ^ near here" , err); } + + { + State state; + ManifestParser parser(&state, NULL); + string err; + EXPECT_FALSE(parser.ParseTest("rule cat\n" + " command = cat\n" + "build $: cat foo\n", + &err)); + EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n" + "build $: cat foo\n" + " ^ near here" + , err); + } + { State state; ManifestParser parser(&state, NULL); @@ -413,10 +429,10 @@ TEST_F(ParserTest, Errors) { ManifestParser parser(&state, NULL); string err; EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n" - "build $: cc bar.cc\n", + "build $.: cc bar.cc\n", &err)); EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n" - "build $: cc bar.cc\n" + "build $.: cc bar.cc\n" " ^ near here" , err); } @@ -425,6 +441,19 @@ TEST_F(ParserTest, Errors) { State state; ManifestParser parser(&state, NULL); string err; + EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n" + "build $: cc bar.cc\n", + &err)); + EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n" + "build $: cc bar.cc\n" + " ^ near here" + , err); + } + + { + State state; + ManifestParser parser(&state, NULL); + string err; EXPECT_FALSE(parser.ParseTest("default\n", &err)); EXPECT_EQ("input:1: expected target name\n" |