[C++] Fix define_with_comments.mk
diff --git a/parser.cc b/parser.cc
index 2816e28..0266f35 100644
--- a/parser.cc
+++ b/parser.cc
@@ -218,12 +218,19 @@
}
void ParseInsideDefine(StringPiece line) {
- if (TrimLeftSpace(line) != "endef") {
+ line = TrimLeftSpace(line);
+ if (GetDirective(line) != "endef") {
if (define_start_ == 0)
define_start_ = l_;
return;
}
+ StringPiece rest = TrimRightSpace(RemoveComment(TrimLeftSpace(
+ line.substr(sizeof("endef")))));
+ if (!rest.empty()) {
+ WARN("%s:%d: extraneous text after `endef' directive", LOCF(loc_));
+ }
+
AssignAST* ast = new AssignAST();
ast->set_loc(Loc(loc_.filename, define_start_line_));
ast->lhs = ParseExpr(define_name_, false);
@@ -298,17 +305,52 @@
}
}
- bool HandleDirective(StringPiece line, const DirectiveMap* directive_map) {
+ StringPiece RemoveComment(StringPiece line) {
+ bool prev_backslash = false;
+ stack<char> paren_stack;
+ for (size_t i = 0; i < line.size(); i++) {
+ char c = line[i];
+ switch (c) {
+ case '(':
+ paren_stack.push(')');
+ break;
+ case '{':
+ paren_stack.push('}');
+ break;
+
+ case ')':
+ case '}':
+ if (!paren_stack.empty() && c == paren_stack.top()) {
+ paren_stack.pop();
+ }
+ break;
+
+ case '#':
+ if (paren_stack.empty() && !prev_backslash)
+ return line.substr(0, i);
+
+ }
+ prev_backslash = c == '\\' && !prev_backslash;
+ }
+ return line;
+ }
+
+ StringPiece GetDirective(StringPiece line) {
if (line.size() < shortest_directive_len_)
- return false;
+ return StringPiece();
StringPiece prefix = line.substr(0, longest_directive_len_ + 1);
- size_t space_index = prefix.find(' ');
- StringPiece directive = prefix.substr(0, space_index);
+ size_t space_index = prefix.find_first_of(" \t#");
+ return prefix.substr(0, space_index);
+ }
+
+ bool HandleDirective(StringPiece line, const DirectiveMap* directive_map) {
+ StringPiece directive = GetDirective(line);
auto found = directive_map->find(directive);
if (found == directive_map->end())
return false;
- StringPiece rest = TrimLeftSpace(line.substr(directive.size() + 1));
+ StringPiece rest = TrimRightSpace(RemoveComment(TrimLeftSpace(
+ line.substr(directive.size() + 1))));
(this->*found->second)(rest, directive);
return true;
}