Permalink
Browse files

reject tabs (and CRs) in input files more aggressively

  • Loading branch information...
1 parent 649ad87 commit ed07eb9f2f25ddee464e786f0f2f82e9e8a33e0a @evmar evmar committed Aug 2, 2012
Showing with 57 additions and 41 deletions.
  1. +19 −18 src/lexer.cc
  2. +5 −2 src/lexer.h
  3. +19 −18 src/lexer.in.cc
  4. +10 −0 src/lexer_test.cc
  5. +3 −2 src/manifest_parser.cc
  6. +1 −1 src/manifest_parser_test.cc
View
@@ -90,24 +90,25 @@ 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 "";
+const char* Lexer::TokenErrorHint(Token expected) {
+ switch (expected) {
+ case COLON:
+ return " ($ also escapes ':')";
+ default:
+ return "";
+ }
+}
+
+string Lexer::DescribeLastError() {
+ if (last_token_) {
+ switch (last_token_[0]) {
+ case '\r':
+ return "carriage returns are not allowed, use newlines";
+ case '\t':
+ return "tabs are not allowed, use spaces";
+ }
}
- return "";
+ return "lexing error";
}
void Lexer::UnreadToken() {
@@ -689,7 +690,7 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
yy95:
{
last_token_ = start;
- return Error("lexing error", err);
+ return Error(DescribeLastError(), err);
}
yy96:
++p;
View
@@ -49,9 +49,12 @@ 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);
+ static const char* TokenErrorHint(Token expected);
+
+ /// If the last token read was an ERROR token, provide more info
+ /// or the empty string.
+ string DescribeLastError();
/// Start parsing some input.
void Start(StringPiece filename, StringPiece input);
View
@@ -89,24 +89,25 @@ 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 "";
+const char* Lexer::TokenErrorHint(Token expected) {
+ switch (expected) {
+ case COLON:
+ return " ($ also escapes ':')";
+ default:
+ return "";
+ }
+}
+
+string Lexer::DescribeLastError() {
+ if (last_token_) {
+ switch (last_token_[0]) {
+ case '\r':
+ return "carriage returns are not allowed, use newlines";
+ case '\t':
+ return "tabs are not allowed, use spaces";
+ }
}
- return "";
+ return "lexing error";
}
void Lexer::UnreadToken() {
@@ -248,7 +249,7 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
}
[^] {
last_token_ = start;
- return Error("lexing error", err);
+ return Error(DescribeLastError(), err);
}
*/
}
View
@@ -85,3 +85,13 @@ TEST(Lexer, CommentEOF) {
Lexer::Token token = lexer.ReadToken();
EXPECT_EQ(Lexer::ERROR, token);
}
+
+TEST(Lexer, Tabs) {
+ // Verify we print a useful error on a disallowed character.
+ Lexer lexer(" \tfoobar");
+ Lexer::Token token = lexer.ReadToken();
+ EXPECT_EQ(Lexer::INDENT, token);
+ token = lexer.ReadToken();
+ EXPECT_EQ(Lexer::ERROR, token);
+ EXPECT_EQ("tabs are not allowed, use spaces", lexer.DescribeLastError());
+}
@@ -76,8 +76,9 @@ bool ManifestParser::Parse(const string& filename, const string& input,
if (!ParseFileInclude(true, err))
return false;
break;
- case Lexer::ERROR:
- return lexer_.Error("lexing error", err);
+ case Lexer::ERROR: {
+ return lexer_.Error(lexer_.DescribeLastError(), err);
+ }
case Lexer::TEOF:
return true;
case Lexer::NEWLINE:
@@ -697,7 +697,7 @@ TEST_F(ParserTest, CRLF) {
EXPECT_FALSE(parser.ParseTest("foo = foo\nbar = bar\r\n",
&err));
- EXPECT_EQ("input:2: lexing error\n"
+ EXPECT_EQ("input:2: carriage returns are not allowed, use newlines\n"
"bar = bar\r\n"
" ^ near here",
err);

0 comments on commit ed07eb9

Please sign in to comment.