1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/test/expectations/parser.h"
7 #include "base/strings/string_util.h"
9 namespace test_expectations
{
11 Parser::Parser(Delegate
* delegate
, const std::string
& input
)
12 : delegate_(delegate
),
23 void Parser::Parse() {
25 end_
= pos_
+ input_
.length();
29 StateFuncPtr state
= &Parser::Start
;
31 state
= (this->*state
)();
35 inline bool Parser::HasNext() {
39 Parser::StateFunc
Parser::Start() {
40 // If at the start of a line is whitespace, skip it and arrange to come back
42 if (IsAsciiWhitespace(*pos_
))
43 return SkipWhitespaceAndNewLines(&Parser::Start
);
45 // Handle comments at the start of lines.
47 return &Parser::ParseComment
;
49 // After arranging to come back here from skipping whitespace and comments,
50 // the parser may be at the end of the input.
54 current_
= Expectation();
57 return &Parser::ParseBugURL
;
60 Parser::StateFunc
Parser::ParseComment() {
62 return SyntaxError("Invalid start of comment");
66 } while (HasNext() && *pos_
!= '\n');
68 return &Parser::Start
;
71 Parser::StateFunc
Parser::ParseBugURL() {
72 return SkipWhitespace(ExtractString(
73 &Parser::BeginModifiers
));
76 Parser::StateFunc
Parser::BeginModifiers() {
77 if (*pos_
!= '[' || !HasNext())
78 return SyntaxError("Expected '[' for start of modifiers");
81 return SkipWhitespace(&Parser::InModifiers
);
84 Parser::StateFunc
Parser::InModifiers() {
86 return &Parser::EndModifiers
;
88 return ExtractString(SkipWhitespace(
89 &Parser::SaveModifier
));
92 Parser::StateFunc
Parser::SaveModifier() {
93 if (extracted_string_
.empty())
94 return SyntaxError("Invalid modifier list");
97 if (ConfigurationFromString(extracted_string_
, &config
)) {
98 if (current_
.configuration
!= CONFIGURATION_UNSPECIFIED
)
99 DataError("Cannot use more than one configuration modifier");
101 current_
.configuration
= config
;
104 if (PlatformFromString(extracted_string_
, &platform
))
105 current_
.platforms
.push_back(platform
);
107 DataError("Invalid modifier string");
110 return SkipWhitespace(&Parser::InModifiers
);
113 Parser::StateFunc
Parser::EndModifiers() {
114 if (*pos_
!= ']' || !HasNext())
115 return SyntaxError("Expected ']' for end of modifiers list");
118 return SkipWhitespace(&Parser::ParseTestName
);
121 Parser::StateFunc
Parser::ParseTestName() {
122 return ExtractString(&Parser::SaveTestName
);
125 Parser::StateFunc
Parser::SaveTestName() {
126 if (extracted_string_
.empty())
127 return SyntaxError("Invalid test name");
129 current_
.test_name
= extracted_string_
.as_string();
130 return SkipWhitespace(&Parser::ParseExpectation
);
133 Parser::StateFunc
Parser::ParseExpectation() {
134 if (*pos_
!= '=' || !HasNext())
135 return SyntaxError("Expected '=' for expectation result");
138 return SkipWhitespace(&Parser::ParseExpectationType
);
141 Parser::StateFunc
Parser::ParseExpectationType() {
142 return ExtractString(&Parser::SaveExpectationType
);
145 Parser::StateFunc
Parser::SaveExpectationType() {
146 if (!ResultFromString(extracted_string_
, ¤t_
.result
))
147 DataError("Unknown expectation type");
149 return SkipWhitespace(&Parser::End
);
152 Parser::StateFunc
Parser::End() {
154 delegate_
->EmitExpectation(current_
);
157 return SkipWhitespaceAndNewLines(&Parser::Start
);
162 Parser::StateFunc
Parser::ExtractString(StateFunc success
) {
163 const char* start
= pos_
;
164 while (!IsAsciiWhitespace(*pos_
) && *pos_
!= ']' && HasNext()) {
167 return SyntaxError("Unexpected start of comment");
170 extracted_string_
= base::StringPiece(start
, pos_
- start
);
174 Parser::StateFunc
Parser::SkipWhitespace(Parser::StateFunc next
) {
175 while ((*pos_
== ' ' || *pos_
== '\t') && HasNext()) {
181 Parser::StateFunc
Parser::SkipWhitespaceAndNewLines(Parser::StateFunc next
) {
182 while (IsAsciiWhitespace(*pos_
) && HasNext()) {
191 Parser::StateFunc
Parser::SyntaxError(const std::string
& message
) {
192 delegate_
->OnSyntaxError(message
);
196 void Parser::DataError(const std::string
& error
) {
198 delegate_
->OnDataError(error
);
201 } // namespace test_expectations