diff options
author | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-06-26 04:02:02 +0900 |
---|---|---|
committer | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-06-26 16:42:23 +0900 |
commit | 420f7754d973242d4120ed67a942bfb386706494 (patch) | |
tree | 0a432b7e9a184ced56695ce4b95a267ebe298108 | |
parent | e919d00f011abdded7b6e5a16888359c5d5996b1 (diff) | |
download | android_build_kati-420f7754d973242d4120ed67a942bfb386706494.tar.gz android_build_kati-420f7754d973242d4120ed67a942bfb386706494.tar.bz2 android_build_kati-420f7754d973242d4120ed67a942bfb386706494.zip |
[C++] Parse override
-rw-r--r-- | ast.h | 8 | ||||
-rw-r--r-- | eval.cc | 5 | ||||
-rw-r--r-- | eval.h | 3 | ||||
-rw-r--r-- | parser.cc | 48 | ||||
-rw-r--r-- | testcase/override_export.mk | 16 | ||||
-rw-r--r-- | testcase/override_override.mk | 15 | ||||
-rw-r--r-- | testcase/override_rule.mk | 8 |
7 files changed, 94 insertions, 9 deletions
@@ -33,10 +33,10 @@ enum struct AssignOp { QUESTION_EQ, }; -enum struct AssignDirective { - NONE, - OVERRIDE, - EXPORT, +enum struct AssignDirective : int { + NONE = 0, + OVERRIDE = 1, + EXPORT = 2, }; enum struct CondOp { @@ -49,8 +49,9 @@ Evaluator::~Evaluator() { } Var* Evaluator::EvalRHS(StringPiece lhs, Value* rhs_v, StringPiece orig_rhs, - AssignOp op) { - const char* origin = is_bootstrap_ ? "default" : "file"; + AssignOp op, bool is_override) { + const char* origin = ( + is_bootstrap_ ? "default" : is_override ? "override" : "file"); Var* rhs = NULL; bool needs_assign = true; @@ -70,7 +70,8 @@ class Evaluator { void set_current_scope(Vars* v) { current_scope_ = v; } private: - Var* EvalRHS(StringPiece lhs, Value* rhs, StringPiece orig_rhs, AssignOp op); + Var* EvalRHS(StringPiece lhs, Value* rhs, StringPiece orig_rhs, AssignOp op, + bool is_override = false); void DoInclude(const char* fname, bool should_exist); const Vars* in_vars_; @@ -77,6 +77,7 @@ class Parser { 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 @@ class Parser { (*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 @@ class Parser { 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 @@ class Parser { return; } + ParseRuleOrAssign(line); + } + + void ParseRuleOrAssign(StringPiece line) { size_t sep = FindTwoOutsideParen(line, ':', '='); if (sep == string::npos) { ParseRule(line, sep); @@ -167,6 +182,13 @@ class Parser { } 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 @@ class Parser { 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 @@ class Parser { 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 @@ class Parser { } } + 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 @@ class Parser { 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 @@ class Parser { 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 @@ void QuitParser() { 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_; diff --git a/testcase/override_export.mk b/testcase/override_export.mk new file mode 100644 index 0000000..99226d4 --- /dev/null +++ b/testcase/override_export.mk @@ -0,0 +1,16 @@ +# TODO: Fix + +override export A:=PASS_A +export override B:=PASS_B +export override define C +PASS_C +endef + +A:=FAIL_A +B:=FAIL_B +C:=FAIL_C + +test: + echo $$A + echo $$B + echo $$C diff --git a/testcase/override_override.mk b/testcase/override_override.mk new file mode 100644 index 0000000..3f66c12 --- /dev/null +++ b/testcase/override_override.mk @@ -0,0 +1,15 @@ +# TODO(go): Fix. + +override A:=PASS_A +A:=FAIL_A + +override define B +PASS_B +endef +B:=FAIL_B + +test: + echo $(A) + echo $(origin A) + echo $(B) + echo $(origin B) diff --git a/testcase/override_rule.mk b/testcase/override_rule.mk new file mode 100644 index 0000000..3811160 --- /dev/null +++ b/testcase/override_rule.mk @@ -0,0 +1,8 @@ +# TODO(go): Fix + +test: override + +A=OK +override : A=PASS +override : + echo $(A) |