[C++] Implement ifeq
diff --git a/parser.cc b/parser.cc
index 0266f35..a8d01ba 100644
--- a/parser.cc
+++ b/parser.cc
@@ -67,6 +67,8 @@
     (*make_directives_)["define"] = &Parser::ParseDefine;
     (*make_directives_)["ifdef"] = &Parser::ParseIfdef;
     (*make_directives_)["ifndef"] = &Parser::ParseIfdef;
+    (*make_directives_)["ifeq"] = &Parser::ParseIfeq;
+    (*make_directives_)["ifneq"] = &Parser::ParseIfeq;
     (*make_directives_)["else"] = &Parser::ParseElse;
     (*make_directives_)["endif"] = &Parser::ParseEndif;
 
@@ -244,6 +246,15 @@
     define_name_.clear();
   }
 
+  void EnterIf(IfAST* ast) {
+    IfState* st = new IfState();
+    st->ast = ast;
+    st->is_in_else = false;
+    st->num_nest = num_if_nest_;
+    if_stack_.push(st);
+    out_asts_ = &ast->true_asts;
+  }
+
   void ParseIfdef(StringPiece line, StringPiece directive) {
     IfAST* ast = new IfAST();
     ast->set_loc(loc_);
@@ -251,13 +262,56 @@
     ast->lhs = ParseExpr(line, false);
     ast->rhs = NULL;
     out_asts_->push_back(ast);
+    EnterIf(ast);
+  }
 
-    IfState* st = new IfState();
-    st->ast = ast;
-    st->is_in_else = false;
-    st->num_nest = num_if_nest_;
-    if_stack_.push(st);
-    out_asts_ = &ast->true_asts;
+  bool ParseIfEqCond(StringPiece s, IfAST* ast) {
+    if (s.empty()) {
+      return false;
+    }
+
+    if (s[0] == '(' && s[s.size() - 1] == ')') {
+      s = s.substr(1, s.size() - 2);
+      char terms[] = {',', '\0'};
+      size_t n;
+      ast->lhs = ParseExprImpl(s, terms, false, &n, true);
+      if (s[n] != ',')
+        return false;
+      s = TrimLeftSpace(s.substr(n+1));
+      ast->rhs = ParseExprImpl(s, NULL, false, &n);
+      return TrimSpace(s.substr(n)) == "";
+    } else {
+      for (int i = 0; i < 2; i++) {
+        if (s.empty())
+          return false;
+        char quote = s[0];
+        if (quote != '\'' && quote != '"')
+          return false;
+        size_t end = s.find(quote, 1);
+        if (end == string::npos)
+          return false;
+        Value* v = ParseExpr(s.substr(1, end - 1), false);
+        if (i == 0)
+          ast->lhs = v;
+        else
+          ast->rhs = v;
+        s = TrimLeftSpace(s.substr(end+1));
+      }
+      return s.empty();
+    }
+  }
+
+  void ParseIfeq(StringPiece line, StringPiece directive) {
+    IfAST* ast = new IfAST();
+    ast->set_loc(loc_);
+    ast->op = directive[2] == 'n' ? CondOp::IFNEQ : CondOp::IFEQ;
+
+    if (!ParseIfEqCond(line, ast)) {
+      Error("*** invalid syntax in conditional.");
+    }
+
+    out_asts_->push_back(ast);
+    EnterIf(ast);
   }
 
   void ParseElse(StringPiece line, StringPiece) {
@@ -350,7 +404,7 @@
       return false;
 
     StringPiece rest = TrimRightSpace(RemoveComment(TrimLeftSpace(
-        line.substr(directive.size() + 1))));
+        line.substr(directive.size()))));
     (this->*found->second)(rest, directive);
     return true;
   }