[libFuzzer] Encapsulate commands in a class.

Summary:
To be more portable (especially w.r.t. platforms without system()),
commands should be managed programmatically rather than via string
manipulation on the command line. This change introduces
Fuzzer::Command, with methods to manage arguments and flags, set output
options, and execute the command.

Patch By: aarongreen

Reviewers: kcc, morehouse

Reviewed By: kcc, morehouse

Subscribers: llvm-commits, mgorny

Differential Revision: https://reviews.llvm.org/D40103

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer@319680 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/FuzzerMerge.cpp b/FuzzerMerge.cpp
index 934871b..5f3052a 100644
--- a/FuzzerMerge.cpp
+++ b/FuzzerMerge.cpp
@@ -9,6 +9,7 @@
 // Merging corpora.
 //===----------------------------------------------------------------------===//
 
+#include "FuzzerCommand.h"
 #include "FuzzerMerge.h"
 #include "FuzzerIO.h"
 #include "FuzzerInternal.h"
@@ -232,7 +233,7 @@
     std::ostringstream StartedLine;
     // Write the pre-run marker.
     OF << "STARTED " << std::dec << i << " " << U.size() << "\n";
-    OF.flush();  // Flush is important since ExecuteCommand may crash.
+    OF.flush();  // Flush is important since Command::Execute may crash.
     // Run.
     TPC.ResetMaps();
     ExecuteCallback(U.data(), U.size());
@@ -332,15 +333,16 @@
 
   // Execute the inner process until it passes.
   // Every inner process should execute at least one input.
-  auto BaseCmd = SplitBefore("-ignore_remaining_args=1",
-                             CloneArgsWithoutX(Args, "merge"));
+  Command BaseCmd(Args);
+  BaseCmd.removeFlag("merge");
   bool Success = false;
   for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) {
     MaybeExitGracefully();
     Printf("MERGE-OUTER: attempt %zd\n", Attempt);
-    auto ExitCode =
-        ExecuteCommand(BaseCmd.first + " -merge_control_file=" + CFPath +
-                       " -merge_inner=1 " + BaseCmd.second);
+    Command Cmd(BaseCmd);
+    Cmd.addFlag("merge_control_file", CFPath);
+    Cmd.addFlag("merge_inner", "1");
+    auto ExitCode = ExecuteCommand(Cmd);
     if (!ExitCode) {
       Printf("MERGE-OUTER: succesfull in %zd attempt(s)\n", Attempt);
       Success = true;