Don't use -- in exec_script

Instead of passing -- in CommandLine construction for exec_script,
which relies on the script running handling --, add a flag to
CommandLine to control its behavior.

This allow script languages that don't support -- as a special
flag.

Change-Id: I2e6d0c2233e4f3cfae8718a7ad98552663216396
Reviewed-on: https://gn-review.googlesource.com/2660
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/base/command_line.cc b/base/command_line.cc
index 67204f0..792d322 100644
--- a/base/command_line.cc
+++ b/base/command_line.cc
@@ -72,10 +72,12 @@
   return true;
 }
 
-// Append switches and arguments, keeping switches before arguments.
+// Append switches and arguments, keeping switches before arguments
+// if handle_switches is true.
 void AppendSwitchesAndArguments(CommandLine* command_line,
-                                const CommandLine::StringVector& argv) {
-  bool parse_switches = true;
+                                const CommandLine::StringVector& argv,
+                                bool handle_switches) {
+  bool parse_switches = handle_switches;
   for (size_t i = 1; i < argv.size(); ++i) {
     CommandLine::StringType arg = argv[i];
 #if defined(OS_WIN)
@@ -155,18 +157,21 @@
 
 }  // namespace
 
-CommandLine::CommandLine(NoProgram no_program) : argv_(1), begin_args_(1) {}
+CommandLine::CommandLine(NoProgram no_program)
+    : argv_(1), begin_args_(1), parse_switches_(true) {}
 
-CommandLine::CommandLine(const FilePath& program) : argv_(1), begin_args_(1) {
+CommandLine::CommandLine(const FilePath& program)
+    : argv_(1), begin_args_(1), parse_switches_(true) {
   SetProgram(program);
 }
 
 CommandLine::CommandLine(int argc, const CommandLine::CharType* const* argv)
-    : argv_(1), begin_args_(1) {
+    : argv_(1), begin_args_(1), parse_switches_(true) {
   InitFromArgv(argc, argv);
 }
 
-CommandLine::CommandLine(const StringVector& argv) : argv_(1), begin_args_(1) {
+CommandLine::CommandLine(const StringVector& argv)
+    : argv_(1), begin_args_(1), parse_switches_(true) {
   InitFromArgv(argv);
 }
 
@@ -257,7 +262,7 @@
   switches_.clear();
   begin_args_ = 1;
   SetProgram(argv.empty() ? FilePath() : FilePath(argv[0]));
-  AppendSwitchesAndArguments(this, argv);
+  AppendSwitchesAndArguments(this, argv, parse_switches_);
 }
 
 FilePath CommandLine::GetProgram() const {
@@ -395,7 +400,7 @@
                                   bool include_program) {
   if (include_program)
     SetProgram(other.GetProgram());
-  AppendSwitchesAndArguments(this, other.argv());
+  AppendSwitchesAndArguments(this, other.argv(), parse_switches_);
 }
 
 void CommandLine::PrependWrapper(const CommandLine::StringType& wrapper) {
@@ -451,7 +456,7 @@
     bool quote_placeholders) const {
   StringType params;
   // Append switches and arguments.
-  bool parse_switches = true;
+  bool parse_switches = parse_switches_;
   for (size_t i = 1; i < argv_.size(); ++i) {
     StringType arg = argv_[i];
     StringType switch_string;
diff --git a/base/command_line.h b/base/command_line.h
index 265fe96..0161457 100644
--- a/base/command_line.h
+++ b/base/command_line.h
@@ -153,6 +153,13 @@
   FilePath GetProgram() const;
   void SetProgram(const FilePath& program);
 
+  // Enables/disables the parsing of switches for future argument appending.
+  // True by default, but can be set to false to ensure that no re-ordering
+  // is done.
+  void SetParseSwitches(bool parse_switches) {
+    parse_switches_ = parse_switches;
+  }
+
   // Returns true if this command line contains the given switch.
   // Switch names must be lowercase.
   // The second override provides an optimized version to avoid inlining codegen
@@ -238,6 +245,9 @@
 
   // The index after the program and switches, any arguments start here.
   size_t begin_args_;
+
+  // Whether or not to parse arguments that look like switches as switches.
+  bool parse_switches_;
 };
 
 }  // namespace base
diff --git a/tools/gn/function_exec_script.cc b/tools/gn/function_exec_script.cc
index e0b6265..15621b7 100644
--- a/tools/gn/function_exec_script.cc
+++ b/tools/gn/function_exec_script.cc
@@ -176,11 +176,9 @@
   const base::FilePath& python_path = build_settings->python_path();
   base::CommandLine cmdline(python_path);
 
-  // CommandLine tries to interpret arguments by default.  Passing "--" disables
-  // this for everything following the "--", so pass this as the very first
-  // thing to python.  Python ignores a -- before the .py file, and this makes
-  // CommandLine let through arguments without modifying them.
-  cmdline.AppendArg("--");
+  // CommandLine tries to interpret arguments by default.  Disable that so
+  // that the arguments will be passed through exactly as specified.
+  cmdline.SetParseSwitches(false);
 
   cmdline.AppendArgPath(script_path);