[C++] Parse override
diff --git a/parser.cc b/parser.cc
index adf59c1..d9611f9 100644
--- a/parser.cc
+++ b/parser.cc
@@ -77,6 +77,7 @@
if (!fixed_lineno_)
loc_.lineno++;
StringPiece line(buf_.data() + l_, e - l_);
+ orig_line_with_directives_ = line;
ParseLine(line);
if (!fixed_lineno_)
loc_.lineno += lf_cnt - 1;
@@ -99,11 +100,19 @@
(*make_directives_)["ifneq"] = &Parser::ParseIfeq;
(*make_directives_)["else"] = &Parser::ParseElse;
(*make_directives_)["endif"] = &Parser::ParseEndif;
+ (*make_directives_)["override"] = &Parser::ParseOverride;
+ (*make_directives_)["export"] = &Parser::ParseExport;
+ (*make_directives_)["unexport"] = &Parser::ParseUnexport;
else_if_directives_ = new DirectiveMap;
(*else_if_directives_)["ifdef"] = &Parser::ParseIfdef;
(*else_if_directives_)["ifndef"] = &Parser::ParseIfdef;
+ assign_directives_ = new DirectiveMap;
+ (*assign_directives_)["define"] = &Parser::ParseDefine;
+ (*assign_directives_)["export"] = &Parser::ParseExport;
+ (*assign_directives_)["override"] = &Parser::ParseOverride;
+
shortest_directive_len_ = 9999;
longest_directive_len_ = 0;
for (auto p : *make_directives_) {
@@ -135,6 +144,8 @@
return;
}
+ current_directive_ = AssignDirective::NONE;
+
if (line[0] == '\t' && state_ != ParserState::NOT_AFTER_RULE) {
CommandAST* ast = new CommandAST();
ast->set_loc(loc_);
@@ -152,6 +163,10 @@
return;
}
+ ParseRuleOrAssign(line);
+ }
+
+ void ParseRuleOrAssign(StringPiece line) {
size_t sep = FindTwoOutsideParen(line, ':', '=');
if (sep == string::npos) {
ParseRule(line, sep);
@@ -167,6 +182,13 @@
}
void ParseRule(StringPiece line, size_t sep) {
+ if (current_directive_ != AssignDirective::NONE) {
+ if (sep != string::npos) {
+ sep += orig_line_with_directives_.size() - line.size();
+ }
+ line = orig_line_with_directives_;
+ }
+
const bool is_rule = sep != string::npos && line[sep] == ':';
RuleAST* ast = new RuleAST();
ast->set_loc(loc_);
@@ -202,7 +224,7 @@
ast->rhs = ParseExpr(rhs);
ast->orig_rhs = rhs;
ast->op = op;
- ast->directive = AssignDirective::NONE;
+ ast->directive = current_directive_;
out_asts_->push_back(ast);
state_ = ParserState::NOT_AFTER_RULE;
}
@@ -249,7 +271,7 @@
ast->rhs = ParseExpr(rhs, ParseExprOpt::DEFINE);
ast->orig_rhs = rhs;
ast->op = AssignOp::EQ;
- ast->directive = AssignDirective::NONE;
+ ast->directive = current_directive_;
out_asts_->push_back(ast);
define_name_.clear();
}
@@ -364,6 +386,23 @@
}
}
+ void ParseOverride(StringPiece line, StringPiece directive) {
+ current_directive_ =
+ static_cast<AssignDirective>(
+ (static_cast<int>(current_directive_) |
+ static_cast<int>(AssignDirective::OVERRIDE)));
+ if (HandleDirective(line, assign_directives_))
+ return;
+
+ ParseRuleOrAssign(line);
+ }
+
+ void ParseExport(StringPiece line, StringPiece) {
+ }
+
+ void ParseUnexport(StringPiece line, StringPiece) {
+ }
+
void CheckIfStack(const char* keyword) {
if (if_stack_.empty()) {
Error(StringPrintf("*** extraneous `%s'.", keyword));
@@ -408,6 +447,9 @@
size_t define_start_;
int define_start_line_;
+ StringPiece orig_line_with_directives_;
+ AssignDirective current_directive_;
+
int num_if_nest_;
stack<IfState*> if_stack_;
@@ -416,6 +458,7 @@
static DirectiveMap* make_directives_;
static DirectiveMap* else_if_directives_;
+ static DirectiveMap* assign_directives_;
static size_t shortest_directive_len_;
static size_t longest_directive_len_;
};
@@ -442,6 +485,7 @@
Parser::DirectiveMap* Parser::make_directives_;
Parser::DirectiveMap* Parser::else_if_directives_;
+Parser::DirectiveMap* Parser::assign_directives_;
size_t Parser::shortest_directive_len_;
size_t Parser::longest_directive_len_;