[C++] Handle .POSIX at eval time

.POSIX pseudo target should change the behavior of $(shell).
This also implements .POSIX for ckati's non-ninja mode.
diff --git a/dep.cc b/dep.cc
index 0a0fc8e..674ac0e 100644
--- a/dep.cc
+++ b/dep.cc
@@ -262,10 +262,6 @@
       for (Symbol t : targets)
         phony_.insert(t);
     }
-    if (GetRuleInputs(Intern(".POSIX"), &targets, &loc)) {
-      // .POSIX: enables bash -e command line option globally
-      g_flags.posix_shell = true;
-    }
     if (GetRuleInputs(Intern(".KATI_RESTAT"), &targets, &loc)) {
       for (Symbol t : targets)
         restat_.insert(t);
diff --git a/eval.cc b/eval.cc
index 4babc39..db1b539 100644
--- a/eval.cc
+++ b/eval.cc
@@ -34,7 +34,9 @@
     : last_rule_(NULL),
       current_scope_(NULL),
       avoid_io_(false),
-      eval_depth_(0) {
+      eval_depth_(0),
+      posix_sym_(Intern(".POSIX")),
+      is_posix_(false) {
 }
 
 Evaluator::~Evaluator() {
@@ -126,6 +128,11 @@
       rule->cmds.push_back(stmt->after_term);
     }
 
+    for (Symbol o : rule->outputs) {
+      if (o == posix_sym_)
+        is_posix_ = true;
+    }
+
     LOG("Rule: %s", rule->DebugString().c_str());
     rules_.push_back(rule);
     last_rule_ = rule;
@@ -311,6 +318,22 @@
   return LookupVar(name)->Eval(this);
 }
 
+string Evaluator::GetShell() {
+  return EvalVar(kShellSym);
+}
+
+string Evaluator::GetShellFlag() {
+  // TODO: Handle $(.SHELLFLAGS)
+  return is_posix_ ? "-ec" : "-c";
+}
+
+string Evaluator::GetShellAndFlag() {
+  string shell = GetShell();
+  shell += ' ';
+  shell += GetShellFlag();
+  return shell;
+}
+
 void Evaluator::Error(const string& msg) {
   ERROR("%s:%d: %s", LOCF(loc_), msg.c_str());
 }
diff --git a/eval.h b/eval.h
index 3eede2b..3f32d5c 100644
--- a/eval.h
+++ b/eval.h
@@ -89,6 +89,10 @@
     eval_depth_--;
   }
 
+  string GetShell();
+  string GetShellFlag();
+  string GetShellAndFlag();
+
  private:
   Var* EvalRHS(Symbol lhs, Value* rhs, StringPiece orig_rhs, AssignOp op,
                bool is_override = false);
@@ -115,6 +119,9 @@
   // error).
   vector<string> delayed_output_commands_;
 
+  Symbol posix_sym_;
+  bool is_posix_;
+
   static unordered_set<Symbol> used_undefined_vars_;
 };
 
diff --git a/exec.cc b/exec.cc
index afba609..081c2f9 100644
--- a/exec.cc
+++ b/exec.cc
@@ -45,7 +45,7 @@
  public:
   explicit Executor(Evaluator* ev)
       : ce_(ev) {
-    shell_ = ev->EvalVar(kShellSym);
+    shell_ = ev->GetShellAndFlag();
   }
 
   double ExecNode(DepNode* n, DepNode* needed_by) {
diff --git a/fileutil.cc b/fileutil.cc
index c116f31..0886def 100644
--- a/fileutil.cc
+++ b/fileutil.cc
@@ -65,7 +65,7 @@
                string* s) {
   string cmd_escaped = cmd;
   EscapeShell(&cmd_escaped);
-  string cmd_with_shell = shell + " -c \"" + cmd_escaped + "\"";
+  string cmd_with_shell = shell + " \"" + cmd_escaped + "\"";
   const char* argv[] = {
     "/bin/sh", "-c", cmd_with_shell.c_str(), NULL
   };
diff --git a/flags.h b/flags.h
index 35c53c4..910acbf 100644
--- a/flags.h
+++ b/flags.h
@@ -34,7 +34,6 @@
   bool is_dry_run;
   bool is_silent_mode;
   bool is_syntax_check_only;
-  bool posix_shell;
   bool regen;
   bool regen_ignoring_kati_binary;
   bool use_find_emulator;
diff --git a/func.cc b/func.cc
index 2e56221..b3d2660 100644
--- a/func.cc
+++ b/func.cc
@@ -562,7 +562,7 @@
     return;
   }
 
-  const string&& shell = ev->EvalVar(kShellSym);
+  const string&& shell = ev->GetShellAndFlag();
 
   string out;
   FindCommand* fc = NULL;
diff --git a/ninja.cc b/ninja.cc
index 762f602..771ddd2 100644
--- a/ninja.cc
+++ b/ninja.cc
@@ -184,8 +184,8 @@
         start_time_(start_time),
         default_target_(NULL) {
     ev_->set_avoid_io(true);
-    shell_ = EscapeNinja(ev->EvalVar(kShellSym));
-    shell_flags_ = g_flags.posix_shell ? "ec" : "c";
+    shell_ = EscapeNinja(ev->GetShell());
+    shell_flags_ = EscapeNinja(ev->GetShellFlag());
     const string use_goma_str = ev->EvalVar(Intern("USE_GOMA"));
     use_goma_ = !(use_goma_str.empty() || use_goma_str == "false");
     if (g_flags.goma_dir)
@@ -502,7 +502,8 @@
         *o << " command = " << shell_ << " $out.rsp\n";
       } else {
         EscapeShell(&cmd_buf);
-        *o << " command = " << shell_ << " -" << shell_flags_ << " \"" << cmd_buf << "\"\n";
+        *o << " command = " << shell_ << ' ' << shell_flags_
+           << " \"" << cmd_buf << "\"\n";
       }
       if (node->is_restat) {
         *o << " restat = 1\n";
diff --git a/testcase/posix_var.mk b/testcase/posix_var.mk
index 466c05d..d516c53 100644
--- a/testcase/posix_var.mk
+++ b/testcase/posix_var.mk
@@ -1,4 +1,4 @@
-# TODO(go|c-exec): Fix
+# TODO(go): Fix
 
 MAKEVER:=$(shell make --version | ruby -n0e 'puts $$_[/Make (\d)/,1]')
 
@@ -10,12 +10,11 @@
 
 else
 
-# TODO: Fix
-#$(info $(shell echo foo))
+$(info $(shell echo foo))
 SHELL := echo
-#$(info $(shell echo bar))
+$(info $(shell echo bar))
 .POSIX:
-#$(info $(shell echo baz))
+$(info $(shell echo baz))
 test:
 	foobar