JDevlieghere created this revision.
JDevlieghere added reviewers: clayborg, labath, zturner, jingham.
JDevlieghere added a project: LLDB.

In order to deal consistently with global state in LLDB, the reproducer feature 
affects LLDB's initialization. For example, when replaying, the FileSystem 
singleton is initialized with a virtual file system.

This is a problem for the driver because it initialized the debugger before 
parsing command line options. The reason is that the driver, among other 
things, checks whether files exists (e.g. core files, target, files to be 
sourced). It also relies on the debugger to parse things like the (scripting) 
language, the architecture, etc.

In an initial attempt I tried to populate the OptionData before the debugger is 
initialized. This proved to be complicated, because of the sanity checks that 
are performed by calling into the debugger of the filesystem. Although it would 
be possible to perform these checks after parsing, it would cause errors to no 
longer appear in the same order as specified by the user, but in an arbitrary 
order specified by the driver implementation. Although I like the idea 
conceptually I don't believe this is an acceptable regression.

Implemented in this patch is a new `ArgParser` class that extracts the existing 
argument parsing logic. Basically it calls `getopt_long_only` repeatedly and 
populates a list with the short option and its value. Because the `ArgParser` 
is //dumb// it can do all its work before the debugger is initialized. 
Afterwards the driver iterates over the options from the argparser (instead of 
calling `getopt_long_only` every time) and do whatever is needed.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D54682

Files:
  tools/driver/Driver.cpp
  tools/driver/Driver.h

Index: tools/driver/Driver.h
===================================================================
--- tools/driver/Driver.h
+++ tools/driver/Driver.h
@@ -16,11 +16,47 @@
 #include <string>
 #include <vector>
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #include "lldb/API/SBBroadcaster.h"
 #include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBError.h"
 
+class ArgParser {
+public:
+  ArgParser(int argc, const char **);
+
+  void Parse();
+
+  struct ParsedOption {
+    ParsedOption(char short_option, std::string option_argument)
+        : short_option(short_option), option_argument(option_argument) {}
+    char short_option;
+    const std::string option_argument;
+  };
+
+  const std::vector<ParsedOption> &GetParsedOptions() const {
+    return m_parsed_options;
+  }
+
+  const std::vector<std::string> &GetRemainingArguments() const {
+    return m_remaining_arguments;
+  }
+
+  bool HasUnknownOrAmbiguousOption() { return m_unknown_or_ambiguous_option; }
+
+private:
+  int m_argc;
+  const char **m_argv;
+  std::vector<option> m_option_table;
+
+  std::vector<ParsedOption> m_parsed_options;
+  std::vector<std::string> m_remaining_arguments;
+  bool m_unknown_or_ambiguous_option = false;
+};
+
 class Driver : public lldb::SBBroadcaster {
 public:
   typedef enum CommandPlacement {
@@ -38,8 +74,7 @@
   /// @return The exit code that the process should return.
   int MainLoop();
 
-  lldb::SBError ParseArgs(int argc, const char *argv[], FILE *out_fh,
-                          bool &do_exit);
+  lldb::SBError ProcessArgs(ArgParser &parser, FILE *out_fh, bool &do_exit);
 
   const char *GetFilename() const;
 
Index: tools/driver/Driver.cpp
===================================================================
--- tools/driver/Driver.cpp
+++ tools/driver/Driver.cpp
@@ -15,8 +15,6 @@
 #include <csignal>
 #include <fcntl.h>
 #include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 
 // Includes for pipe()
@@ -171,10 +169,128 @@
     {LLDB_OPT_SET_7, true, "repl-language", 'R', required_argument, 0,
      eArgTypeNone, "Chooses the language for the REPL."}};
 
-static constexpr auto g_num_options = sizeof(g_options)/sizeof(OptionDefinition);
+static constexpr auto g_num_options =
+    sizeof(g_options) / sizeof(OptionDefinition);
 
 static const uint32_t last_option_set_with_args = 2;
 
+static void BuildGetOptTable(std::vector<option> &getopt_table) {
+  getopt_table.resize(g_num_options + 1);
+
+  std::bitset<256> option_seen;
+  uint32_t j = 0;
+  for (const auto &opt : g_options) {
+    char short_opt = opt.short_option;
+
+    if (option_seen.test(short_opt) == false) {
+      getopt_table[j].name = opt.long_option;
+      getopt_table[j].has_arg = opt.option_has_arg;
+      getopt_table[j].flag = NULL;
+      getopt_table[j].val = opt.short_option;
+      option_seen.set(short_opt);
+      ++j;
+    }
+  }
+
+  getopt_table[j].name = NULL;
+  getopt_table[j].has_arg = 0;
+  getopt_table[j].flag = NULL;
+  getopt_table[j].val = 0;
+}
+
+ArgParser::ArgParser(int argc, const char **argv)
+    : m_argc(argc), m_argv(argv) {}
+
+void ArgParser::Parse() {
+  // Build option table.
+  BuildGetOptTable(m_option_table);
+
+  assert(!m_option_table.empty());
+
+  // Build the option_string argument for call to getopt_long_only.
+  std::string option_string;
+  auto sentinel_it = std::prev(std::end(m_option_table));
+  for (auto long_opt_it = std::begin(m_option_table);
+       long_opt_it != sentinel_it; ++long_opt_it) {
+    if (long_opt_it->flag == nullptr) {
+      option_string.push_back(static_cast<char>(long_opt_it->val));
+      switch (long_opt_it->has_arg) {
+      default:
+      case no_argument:
+        break;
+      case required_argument:
+        option_string.push_back(':');
+        break;
+      case optional_argument:
+        option_string.append("::");
+        break;
+      }
+    }
+  }
+
+  // Prepare for and make calls to getopt_long_only.
+#if __GLIBC__
+  optind = 0;
+#else
+  optreset = 1;
+  optind = 1;
+#endif
+  int val;
+  while (true) {
+    int long_options_index = -1;
+    val = ::getopt_long_only(m_argc, const_cast<char **>(m_argv),
+                             option_string.c_str(), m_option_table.data(),
+                             &long_options_index);
+
+    // End of option list.
+    if (val == -1)
+      break;
+
+    // Unknown option.
+    if (val == '?') {
+      m_unknown_or_ambiguous_option = true;
+      break;
+    }
+
+    if (val == 0)
+      continue;
+
+    if (long_options_index == -1) {
+      auto long_opt_it = std::find_if(
+          std::begin(m_option_table), sentinel_it,
+          [val](const option &long_option) { return long_option.val == val; });
+      if (std::end(m_option_table) != long_opt_it)
+        long_options_index =
+            std::distance(std::begin(m_option_table), long_opt_it);
+    }
+
+    if (long_options_index < 0) {
+      m_unknown_or_ambiguous_option = true;
+      break;
+    }
+
+    const OptionDefinition option_definition = g_options[long_options_index];
+    m_parsed_options.emplace_back(
+        option_definition.short_option,
+        option_definition.option_has_arg ? std::string(optarg) : "");
+  }
+
+  // Any arguments that are left over after option parsing are for the
+  // program.
+
+  // Skip any options we consumed with getopt_long_only
+  m_argc -= optind;
+  m_argv += optind;
+
+  if (m_argc > 0) {
+    for (int arg_idx = 0; arg_idx < m_argc; ++arg_idx) {
+      const char *arg = m_argv[arg_idx];
+      if (arg)
+        m_remaining_arguments.push_back(arg);
+    }
+  }
+}
+
 Driver::Driver()
     : SBBroadcaster("Driver"), m_debugger(SBDebugger::Create(false)),
       m_option_data() {
@@ -240,7 +356,7 @@
   }
 }
 
-static void ShowUsage(FILE *out, Driver::OptionData data) {
+static void ShowUsage(FILE *out) {
   uint32_t screen_width = 80;
   uint32_t indent_level = 0;
   const char *name = "lldb";
@@ -304,8 +420,7 @@
           if (opt.option_has_arg == required_argument)
             fprintf(out, " [-%c <%s>]", opt.short_option, arg_name);
           else if (opt.option_has_arg == optional_argument)
-            fprintf(out, " [-%c [<%s>]]", opt.short_option,
-                    arg_name);
+            fprintf(out, " [-%c [<%s>]]", opt.short_option, arg_name);
           else
             fprintf(out, " [-%c]", opt.short_option);
         }
@@ -351,8 +466,7 @@
         fprintf(out, "<%s>", arg_name);
       fprintf(out, "\n");
       indent_level += 5;
-      OutputFormattedUsageText(out, indent_level, opt.usage_text,
-                               screen_width);
+      OutputFormattedUsageText(out, indent_level, opt.usage_text, screen_width);
       indent_level -= 5;
       fprintf(out, "\n");
     }
@@ -388,30 +502,6 @@
       "");
 }
 
- static void BuildGetOptTable(std::vector<option> &getopt_table) {
-  getopt_table.resize(g_num_options + 1);
-
-  std::bitset<256> option_seen;
-  uint32_t j = 0;
-  for (const auto &opt : g_options) {
-    char short_opt = opt.short_option;
-
-    if (option_seen.test(short_opt) == false) {
-      getopt_table[j].name = opt.long_option;
-      getopt_table[j].has_arg = opt.option_has_arg;
-      getopt_table[j].flag = NULL;
-      getopt_table[j].val = opt.short_option;
-      option_seen.set(short_opt);
-      ++j;
-    }
-  }
-
-  getopt_table[j].name = NULL;
-  getopt_table[j].has_arg = 0;
-  getopt_table[j].flag = NULL;
-  getopt_table[j].val = 0;
-}
-
 Driver::OptionData::OptionData()
     : m_args(), m_script_lang(lldb::eScriptLanguageDefault), m_core_file(),
       m_crash_log(), m_initial_commands(), m_after_file_commands(),
@@ -441,9 +531,8 @@
   // Only read .lldbinit in the current working directory
   // if it's not the same as the .lldbinit in the home
   // directory (which is already being read in).
-  if (local_lldbinit.Exists() &&
-      strcmp(local_lldbinit.GetDirectory(), homedir_dot_lldb.GetDirectory()) !=
-          0) {
+  if (local_lldbinit.Exists() && strcmp(local_lldbinit.GetDirectory(),
+                                        homedir_dot_lldb.GetDirectory()) != 0) {
     char path[2048];
     local_lldbinit.GetPath(path, 2047);
     InitialCmdEntry entry(path, true, true, true);
@@ -579,39 +668,16 @@
 // arguments were invalid OR
 // if the user only wanted help or version information.
 
-SBError Driver::ParseArgs(int argc, const char *argv[], FILE *out_fh,
-                          bool &exiting) {
+SBError Driver::ProcessArgs(ArgParser &parser, FILE *out_fh, bool &exiting) {
   static_assert(g_num_options > 0, "cannot handle arguments");
 
   ResetOptionValues();
 
   SBError error;
-  std::vector<option> long_options_vector;
-  BuildGetOptTable(long_options_vector);
-  if (long_options_vector.empty()) {
-    error.SetErrorStringWithFormat("invalid long options");
-    return error;
-  }
 
-  // Build the option_string argument for call to getopt_long_only.
-  std::string option_string;
-  auto sentinel_it = std::prev(std::end(long_options_vector));
-  for (auto long_opt_it = std::begin(long_options_vector);
-            long_opt_it != sentinel_it; ++long_opt_it) {
-    if (long_opt_it->flag == nullptr) {
-      option_string.push_back(static_cast<char>(long_opt_it->val));
-      switch (long_opt_it->has_arg) {
-      default:
-      case no_argument:
-        break;
-      case required_argument:
-        option_string.push_back(':');
-        break;
-      case optional_argument:
-        option_string.append("::");
-        break;
-      }
-    }
+  if (parser.HasUnknownOrAmbiguousOption()) {
+    error.SetErrorStringWithFormat("unknown or ambiguous option");
+    return error;
   }
 
   // This is kind of a pain, but since we make the debugger in the Driver's
@@ -627,199 +693,159 @@
   m_debugger.SkipLLDBInitFiles(false);
   m_debugger.SkipAppInitFiles(false);
 
-// Prepare for & make calls to getopt_long_only.
-#if __GLIBC__
-  optind = 0;
-#else
-  optreset = 1;
-  optind = 1;
-#endif
-  int val;
-  while (1) {
-    int long_options_index = -1;
-    val = ::getopt_long_only(argc, const_cast<char **>(argv),
-                             option_string.c_str(), long_options_vector.data(),
-                             &long_options_index);
+  for (auto parsed_option : parser.GetParsedOptions()) {
+    const char *optarg = parsed_option.option_argument.c_str();
+    switch (parsed_option.short_option) {
+    case 'h':
+      m_option_data.m_print_help = true;
+      break;
 
-    if (val == -1)
+    case 'v':
+      m_option_data.m_print_version = true;
       break;
-    else if (val == '?') {
-      m_option_data.m_print_help = true;
-      error.SetErrorStringWithFormat("unknown or ambiguous option");
+
+    case 'P':
+      m_option_data.m_print_python_path = true;
       break;
-    } else if (val == 0)
-      continue;
-    else {
-      m_option_data.m_seen_options.insert((char)val);
-      if (long_options_index == -1) {
-        auto long_opt_it = std::find_if(std::begin(long_options_vector), sentinel_it,
-            [val](const option &long_option) { return long_option.val == val; });
-        if (std::end(long_options_vector) != long_opt_it)
-          long_options_index =
-              std::distance(std::begin(long_options_vector), long_opt_it);
-      }
 
-      if (long_options_index >= 0) {
-        const int short_option = g_options[long_options_index].short_option;
-
-        switch (short_option) {
-        case 'h':
-          m_option_data.m_print_help = true;
-          break;
-
-        case 'v':
-          m_option_data.m_print_version = true;
-          break;
-
-        case 'P':
-          m_option_data.m_print_python_path = true;
-          break;
-
-        case 'b':
-          m_option_data.m_batch = true;
-          break;
-
-        case 'c': {
-          SBFileSpec file(optarg);
-          if (file.Exists()) {
-            m_option_data.m_core_file = optarg;
-          } else
-            error.SetErrorStringWithFormat(
-                "file specified in --core (-c) option doesn't exist: '%s'",
-                optarg);
-        } break;
-
-        case 'e':
-          m_option_data.m_use_external_editor = true;
-          break;
-
-        case 'x':
-          m_debugger.SkipLLDBInitFiles(true);
-          m_debugger.SkipAppInitFiles(true);
-          break;
-
-        case 'X':
-          m_debugger.SetUseColor(false);
-          break;
-
-        case 'f': {
-          SBFileSpec file(optarg);
-          if (file.Exists()) {
-            m_option_data.m_args.push_back(optarg);
-          } else if (file.ResolveExecutableLocation()) {
-            char path[PATH_MAX];
-            file.GetPath(path, sizeof(path));
-            m_option_data.m_args.push_back(path);
-          } else
-            error.SetErrorStringWithFormat(
-                "file specified in --file (-f) option doesn't exist: '%s'",
-                optarg);
-        } break;
-
-        case 'a':
-          if (!m_debugger.SetDefaultArchitecture(optarg))
-            error.SetErrorStringWithFormat(
-                "invalid architecture in the -a or --arch option: '%s'",
-                optarg);
-          break;
-
-        case 'l':
-          m_option_data.m_script_lang = m_debugger.GetScriptingLanguage(optarg);
-          break;
-
-        case 'd':
-          m_option_data.m_debug_mode = true;
-          break;
-
-        case 'z': {
-          SBFileSpec file(optarg);
-          if (file.Exists()) {
-            m_debugger.SetReproducerPath(optarg);
-          } else
-            error.SetErrorStringWithFormat("file specified in --reproducer "
-                                           "(-z) option doesn't exist: '%s'",
-                                           optarg);
-        } break;
-
-        case 'Q':
-          m_option_data.m_source_quietly = true;
-          break;
-
-        case 'K':
-          m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash,
-                                          true, error);
-          break;
-        case 'k':
-          m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash,
-                                          false, error);
-          break;
-
-        case 'n':
-          m_option_data.m_process_name = optarg;
-          break;
-
-        case 'w':
-          m_option_data.m_wait_for = true;
-          break;
-
-        case 'p': {
-          char *remainder;
-          m_option_data.m_process_pid = strtol(optarg, &remainder, 0);
-          if (remainder == optarg || *remainder != '\0')
-            error.SetErrorStringWithFormat(
-                "Could not convert process PID: \"%s\" into a pid.", optarg);
-        } break;
-
-        case 'r':
-          m_option_data.m_repl = true;
-          if (optarg && optarg[0])
-            m_option_data.m_repl_options = optarg;
-          else
-            m_option_data.m_repl_options.clear();
-          break;
-
-        case 'R':
-          m_option_data.m_repl_lang =
-              SBLanguageRuntime::GetLanguageTypeFromString(optarg);
-          if (m_option_data.m_repl_lang == eLanguageTypeUnknown) {
-            error.SetErrorStringWithFormat("Unrecognized language name: \"%s\"",
-                                           optarg);
-          }
-          break;
-
-        case 's':
-          m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile,
-                                          true, error);
-          break;
-        case 'o':
-          m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile,
-                                          false, error);
-          break;
-        case 'S':
-          m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile,
-                                          true, error);
-          break;
-        case 'O':
-          m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile,
-                                          false, error);
-          break;
-        default:
-          m_option_data.m_print_help = true;
-          error.SetErrorStringWithFormat("unrecognized option %c",
-                                         short_option);
-          break;
-        }
-      } else {
-        error.SetErrorStringWithFormat("invalid option with value %i", val);
-      }
-      if (error.Fail()) {
-        return error;
+    case 'b':
+      m_option_data.m_batch = true;
+      break;
+
+    case 'c': {
+      SBFileSpec file(optarg);
+      if (file.Exists()) {
+        m_option_data.m_core_file = optarg;
+      } else
+        error.SetErrorStringWithFormat(
+            "file specified in --core (-c) option doesn't exist: '%s'", optarg);
+    } break;
+
+    case 'e':
+      m_option_data.m_use_external_editor = true;
+      break;
+
+    case 'x':
+      m_debugger.SkipLLDBInitFiles(true);
+      m_debugger.SkipAppInitFiles(true);
+      break;
+
+    case 'X':
+      m_debugger.SetUseColor(false);
+      break;
+
+    case 'f': {
+      SBFileSpec file(optarg);
+      if (file.Exists()) {
+        m_option_data.m_args.push_back(optarg);
+      } else if (file.ResolveExecutableLocation()) {
+        char path[PATH_MAX];
+        file.GetPath(path, sizeof(path));
+        m_option_data.m_args.push_back(path);
+      } else
+        error.SetErrorStringWithFormat(
+            "file specified in --file (-f) option doesn't exist: '%s'", optarg);
+    } break;
+
+    case 'a':
+      if (!m_debugger.SetDefaultArchitecture(optarg))
+        error.SetErrorStringWithFormat(
+            "invalid architecture in the -a or --arch option: '%s'", optarg);
+      break;
+
+    case 'l':
+      m_option_data.m_script_lang = m_debugger.GetScriptingLanguage(optarg);
+      break;
+
+    case 'd':
+      m_option_data.m_debug_mode = true;
+      break;
+
+    case 'z': {
+      SBFileSpec file(optarg);
+      if (file.Exists()) {
+        m_debugger.SetReproducerPath(optarg);
+      } else
+        error.SetErrorStringWithFormat("file specified in --reproducer "
+                                       "(-z) option doesn't exist: '%s'",
+                                       optarg);
+    } break;
+
+    case 'Q':
+      m_option_data.m_source_quietly = true;
+      break;
+
+    case 'K':
+      m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, true,
+                                      error);
+      break;
+    case 'k':
+      m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash,
+                                      false, error);
+      break;
+
+    case 'n':
+      m_option_data.m_process_name = optarg;
+      break;
+
+    case 'w':
+      m_option_data.m_wait_for = true;
+      break;
+
+    case 'p': {
+      char *remainder;
+      m_option_data.m_process_pid = strtol(optarg, &remainder, 0);
+      if (remainder == optarg || *remainder != '\0')
+        error.SetErrorStringWithFormat(
+            "Could not convert process PID: \"%s\" into a pid.", optarg);
+    } break;
+
+    case 'r':
+      m_option_data.m_repl = true;
+      if (optarg && optarg[0])
+        m_option_data.m_repl_options = optarg;
+      else
+        m_option_data.m_repl_options.clear();
+      break;
+
+    case 'R':
+      m_option_data.m_repl_lang =
+          SBLanguageRuntime::GetLanguageTypeFromString(optarg);
+      if (m_option_data.m_repl_lang == eLanguageTypeUnknown) {
+        error.SetErrorStringWithFormat("Unrecognized language name: \"%s\"",
+                                       optarg);
       }
+      break;
+
+    case 's':
+      m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, true,
+                                      error);
+      break;
+    case 'o':
+      m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, false,
+                                      error);
+      break;
+    case 'S':
+      m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, true,
+                                      error);
+      break;
+    case 'O':
+      m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile,
+                                      false, error);
+      break;
+    default:
+      m_option_data.m_print_help = true;
+      error.SetErrorStringWithFormat("unrecognized option %c",
+                                     parsed_option.short_option);
+      break;
+    }
+    if (error.Fail()) {
+      return error;
     }
   }
 
-  if (error.Fail() || m_option_data.m_print_help) {
-    ShowUsage(out_fh, m_option_data);
+  if (m_option_data.m_print_help) {
+    ShowUsage(out_fh);
     exiting = true;
   } else if (m_option_data.m_print_version) {
     ::fprintf(out_fh, "%s\n", m_debugger.GetVersionString());
@@ -838,29 +864,14 @@
     exiting = true;
   } else if (m_option_data.m_process_name.empty() &&
              m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) {
-    // Any arguments that are left over after option parsing are for
-    // the program. If a file was specified with -f then the filename
-    // is already in the m_option_data.m_args array, and any remaining args
-    // are arguments for the inferior program. If no file was specified with
-    // -f, then what is left is the program name followed by any arguments.
-
-    // Skip any options we consumed with getopt_long_only
-    argc -= optind;
-    argv += optind;
-
-    if (argc > 0) {
-      for (int arg_idx = 0; arg_idx < argc; ++arg_idx) {
-        const char *arg = argv[arg_idx];
-        if (arg)
-          m_option_data.m_args.push_back(arg);
-      }
-    }
-
+    // If a file was specified with -f then the filename is already in the
+    // m_option_data.m_args array, and any remaining args are arguments for the
+    // inferior program. If no file was specified with -f, then what is left is
+    // the program name followed by any arguments.
+    for (auto &str : parser.GetRemainingArguments())
+      m_option_data.m_args.push_back(str);
   } else {
-    // Skip any options we consumed with getopt_long_only
-    argc -= optind;
-
-    if (argc > 0)
+    if (!parser.GetRemainingArguments().empty())
       ::fprintf(out_fh,
                 "Warning: program arguments are ignored when attaching.\n");
   }
@@ -884,8 +895,9 @@
   if (err == 0) {
     ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
     if (nrwr < 0) {
-      fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
-                      "when trying to open LLDB commands pipe\n",
+      fprintf(stderr,
+              "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
+              "when trying to open LLDB commands pipe\n",
               fds[WRITE], static_cast<const void *>(commands_data),
               static_cast<uint64_t>(commands_size), errno);
     } else if (static_cast<size_t>(nrwr) == commands_size) {
@@ -903,13 +915,13 @@
       // the debugger as an input handle
       commands_file = fdopen(fds[READ], "r");
       if (commands_file) {
-        fds[READ] =
-            -1; // The FILE * 'commands_file' now owns the read descriptor
-                // Hand ownership if the FILE * over to the debugger for
-                // "commands_file".
+        fds[READ] = -1; // The FILE * 'commands_file' now owns the read
+                        // descriptor Hand ownership if the FILE * over to the
+                        // debugger for "commands_file".
       } else {
-        fprintf(stderr, "error: fdopen(%i, \"r\") failed (errno = %i) when "
-                        "trying to open LLDB commands pipe\n",
+        fprintf(stderr,
+                "error: fdopen(%i, \"r\") failed (errno = %i) when "
+                "trying to open LLDB commands pipe\n",
                 fds[READ], errno);
       }
     }
@@ -1228,6 +1240,9 @@
   llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
   llvm::PrettyStackTraceProgram X(argc, argv);
 
+  ArgParser parser(argc, argv);
+  parser.Parse();
+
   SBDebugger::Initialize();
 
   SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
@@ -1247,7 +1262,7 @@
     Driver driver;
 
     bool exiting = false;
-    SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
+    SBError error(driver.ProcessArgs(parser, stdout, exiting));
     if (error.Fail()) {
       exit_code = 1;
       const char *error_cstr = error.GetCString();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to