//===-- Driver.cpp ----------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Driver.h"

#include <atomic>
#include <csignal>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Includes for pipe()
#if defined(_WIN32)
#include <fcntl.h>
#include <io.h>
#else
#include <unistd.h>
#endif

#include <string>

#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBCommunication.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBLanguageRuntime.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include <thread>

#if !defined(__APPLE__)
#include "llvm/Support/DataTypes.h"
#endif

using namespace lldb;

static void reset_stdin_termios();
static bool g_old_stdin_termios_is_valid = false;
static struct termios g_old_stdin_termios;

static Driver *g_driver = NULL;

// In the Driver::MainLoop, we change the terminal settings.  This function is
// added as an atexit handler to make sure we clean them up.
static void reset_stdin_termios() {
  if (g_old_stdin_termios_is_valid) {
    g_old_stdin_termios_is_valid = false;
    ::tcsetattr(STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
  }
}

typedef struct {
  uint32_t usage_mask; // Used to mark options that can be used together.  If (1
                       // << n & usage_mask) != 0
                       // then this option belongs to option set n.
  bool required;       // This option is required (in the current usage level)
  const char *long_option; // Full name for this option.
  int short_option;        // Single character for this option.
  int option_has_arg; // no_argument, required_argument or optional_argument
  uint32_t completion_type; // Cookie the option class can use to do define the
                            // argument completion.
  lldb::CommandArgumentType argument_type; // Type of argument this option takes
  const char *usage_text; // Full text explaining what this options does and
                          // what (if any) argument to
                          // pass it.
} OptionDefinition;

#define LLDB_3_TO_5 LLDB_OPT_SET_3 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5
#define LLDB_4_TO_5 LLDB_OPT_SET_4 | LLDB_OPT_SET_5

static OptionDefinition g_options[] = {
    {LLDB_OPT_SET_1, true, "help", 'h', no_argument, 0, eArgTypeNone,
     "Prints out the usage information for the LLDB debugger."},
    {LLDB_OPT_SET_2, true, "version", 'v', no_argument, 0, eArgTypeNone,
     "Prints out the current version number of the LLDB debugger."},
    {LLDB_OPT_SET_3, true, "arch", 'a', required_argument, 0,
     eArgTypeArchitecture,
     "Tells the debugger to use the specified architecture when starting and "
     "running the program.  <architecture> must "
     "be one of the architectures for which the program was compiled."},
    {LLDB_OPT_SET_3, true, "file", 'f', required_argument, 0, eArgTypeFilename,
     "Tells the debugger to use the file <filename> as the program to be "
     "debugged."},
    {LLDB_OPT_SET_3, false, "core", 'c', required_argument, 0, eArgTypeFilename,
     "Tells the debugger to use the fullpath to <path> as the core file."},
    {LLDB_OPT_SET_5, true, "attach-pid", 'p', required_argument, 0, eArgTypePid,
     "Tells the debugger to attach to a process with the given pid."},
    {LLDB_OPT_SET_4, true, "attach-name", 'n', required_argument, 0,
     eArgTypeProcessName,
     "Tells the debugger to attach to a process with the given name."},
    {LLDB_OPT_SET_4, true, "wait-for", 'w', no_argument, 0, eArgTypeNone,
     "Tells the debugger to wait for a process with the given pid or name to "
     "launch before attaching."},
    {LLDB_3_TO_5, false, "source", 's', required_argument, 0, eArgTypeFilename,
     "Tells the debugger to read in and execute the lldb commands in the given "
     "file, after any file provided on the command line has been loaded."},
    {LLDB_3_TO_5, false, "one-line", 'o', required_argument, 0, eArgTypeNone,
     "Tells the debugger to execute this one-line lldb command after any file "
     "provided on the command line has been loaded."},
    {LLDB_3_TO_5, false, "source-before-file", 'S', required_argument, 0,
     eArgTypeFilename, "Tells the debugger to read in and execute the lldb "
                       "commands in the given file, before any file provided "
                       "on the command line has been loaded."},
    {LLDB_3_TO_5, false, "one-line-before-file", 'O', required_argument, 0,
     eArgTypeNone, "Tells the debugger to execute this one-line lldb command "
                   "before any file provided on the command line has been "
                   "loaded."},
    {LLDB_3_TO_5, false, "one-line-on-crash", 'k', required_argument, 0,
     eArgTypeNone, "When in batch mode, tells the debugger to execute this "
                   "one-line lldb command if the target crashes."},
    {LLDB_3_TO_5, false, "source-on-crash", 'K', required_argument, 0,
     eArgTypeFilename, "When in batch mode, tells the debugger to source this "
                       "file of lldb commands if the target crashes."},
    {LLDB_3_TO_5, false, "source-quietly", 'Q', no_argument, 0, eArgTypeNone,
     "Tells the debugger to execute this one-line lldb command before any file "
     "provided on the command line has been loaded."},
    {LLDB_3_TO_5, false, "batch", 'b', no_argument, 0, eArgTypeNone,
     "Tells the debugger to run the commands from -s, -S, -o & -O, and "
     "then quit.  However if any run command stopped due to a signal or crash, "
     "the debugger will return to the interactive prompt at the place of the "
     "crash."},
    {LLDB_3_TO_5, false, "editor", 'e', no_argument, 0, eArgTypeNone,
     "Tells the debugger to open source files using the host's \"external "
     "editor\" mechanism."},
    {LLDB_3_TO_5, false, "no-lldbinit", 'x', no_argument, 0, eArgTypeNone,
     "Do not automatically parse any '.lldbinit' files."},
    {LLDB_3_TO_5, false, "no-use-colors", 'X', no_argument, 0, eArgTypeNone,
     "Do not use colors."},
    {LLDB_OPT_SET_6, true, "python-path", 'P', no_argument, 0, eArgTypeNone,
     "Prints out the path to the lldb.py file for this version of lldb."},
    {LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0,
     eArgTypeScriptLang,
     "Tells the debugger to use the specified scripting language for "
     "user-defined scripts, rather than the default.  "
     "Valid scripting languages that can be specified include Python, Perl, "
     "Ruby and Tcl.  Currently only the Python "
     "extensions have been implemented."},
    {LLDB_3_TO_5, false, "debug", 'd', no_argument, 0, eArgTypeNone,
     "Tells the debugger to print out extra information for debugging itself."},
    {LLDB_OPT_SET_7, true, "repl", 'r', optional_argument, 0, eArgTypeNone,
     "Runs lldb in REPL mode with a stub process."},
    {LLDB_OPT_SET_7, true, "repl-language", 'R', required_argument, 0,
     eArgTypeNone, "Chooses the language for the REPL."},
    {0, false, NULL, 0, 0, 0, eArgTypeNone, NULL}};

static const uint32_t last_option_set_with_args = 2;

Driver::Driver()
    : SBBroadcaster("Driver"), m_debugger(SBDebugger::Create(false)),
      m_option_data() {
  // We want to be able to handle CTRL+D in the terminal to have it terminate
  // certain input
  m_debugger.SetCloseInputOnEOF(false);
  g_driver = this;
}

Driver::~Driver() { g_driver = NULL; }

// This function takes INDENT, which tells how many spaces to output at the
// front
// of each line; TEXT, which is the text that is to be output. It outputs the
// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
// front of each line.  It breaks lines on spaces, tabs or newlines, shortening
// the line if necessary to not break in the middle of a word. It assumes that
// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.

void OutputFormattedUsageText(FILE *out, int indent, const char *text,
                              int output_max_columns) {
  int len = strlen(text);
  std::string text_string(text);

  // Force indentation to be reasonable.
  if (indent >= output_max_columns)
    indent = 0;

  // Will it all fit on one line?

  if (len + indent < output_max_columns)
    // Output as a single line
    fprintf(out, "%*s%s\n", indent, "", text);
  else {
    // We need to break it up into multiple lines.
    int text_width = output_max_columns - indent - 1;
    int start = 0;
    int end = start;
    int final_end = len;
    int sub_len;

    while (end < final_end) {
      // Dont start the 'text' on a space, since we're already outputting the
      // indentation.
      while ((start < final_end) && (text[start] == ' '))
        start++;

      end = start + text_width;
      if (end > final_end)
        end = final_end;
      else {
        // If we're not at the end of the text, make sure we break the line on
        // white space.
        while (end > start && text[end] != ' ' && text[end] != '\t' &&
               text[end] != '\n')
          end--;
      }
      sub_len = end - start;
      std::string substring = text_string.substr(start, sub_len);
      fprintf(out, "%*s%s\n", indent, "", substring.c_str());
      start = end + 1;
    }
  }
}

void ShowUsage(FILE *out, OptionDefinition *option_table,
               Driver::OptionData data) {
  uint32_t screen_width = 80;
  uint32_t indent_level = 0;
  const char *name = "lldb";

  fprintf(out, "\nUsage:\n\n");

  indent_level += 2;

  // First, show each usage level set of options, e.g. <cmd>
  // [options-for-level-0]
  //                                                   <cmd>
  //                                                   [options-for-level-1]
  //                                                   etc.

  uint32_t num_options;
  uint32_t num_option_sets = 0;

  for (num_options = 0; option_table[num_options].long_option != NULL;
       ++num_options) {
    uint32_t this_usage_mask = option_table[num_options].usage_mask;
    if (this_usage_mask == LLDB_OPT_SET_ALL) {
      if (num_option_sets == 0)
        num_option_sets = 1;
    } else {
      for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) {
        if (this_usage_mask & 1 << j) {
          if (num_option_sets <= j)
            num_option_sets = j + 1;
        }
      }
    }
  }

  for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++) {
    uint32_t opt_set_mask;

    opt_set_mask = 1 << opt_set;

    if (opt_set > 0)
      fprintf(out, "\n");
    fprintf(out, "%*s%s", indent_level, "", name);
    bool is_help_line = false;

    for (uint32_t i = 0; i < num_options; ++i) {
      if (option_table[i].usage_mask & opt_set_mask) {
        CommandArgumentType arg_type = option_table[i].argument_type;
        const char *arg_name =
            SBCommandInterpreter::GetArgumentTypeAsCString(arg_type);
        // This is a bit of a hack, but there's no way to say certain options
        // don't have arguments yet...
        // so we do it by hand here.
        if (option_table[i].short_option == 'h')
          is_help_line = true;

        if (option_table[i].required) {
          if (option_table[i].option_has_arg == required_argument)
            fprintf(out, " -%c <%s>", option_table[i].short_option, arg_name);
          else if (option_table[i].option_has_arg == optional_argument)
            fprintf(out, " -%c [<%s>]", option_table[i].short_option, arg_name);
          else
            fprintf(out, " -%c", option_table[i].short_option);
        } else {
          if (option_table[i].option_has_arg == required_argument)
            fprintf(out, " [-%c <%s>]", option_table[i].short_option, arg_name);
          else if (option_table[i].option_has_arg == optional_argument)
            fprintf(out, " [-%c [<%s>]]", option_table[i].short_option,
                    arg_name);
          else
            fprintf(out, " [-%c]", option_table[i].short_option);
        }
      }
    }
    if (!is_help_line && (opt_set <= last_option_set_with_args))
      fprintf(out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
  }

  fprintf(out, "\n\n");

  // Now print out all the detailed information about the various options:  long
  // form, short form and help text:
  //   -- long_name <argument>
  //   - short <argument>
  //   help text

  // This variable is used to keep track of which options' info we've printed
  // out, because some options can be in
  // more than one usage level, but we only want to print the long form of its
  // information once.

  Driver::OptionData::OptionSet options_seen;
  Driver::OptionData::OptionSet::iterator pos;

  indent_level += 5;

  for (uint32_t i = 0; i < num_options; ++i) {
    // Only print this option if we haven't already seen it.
    pos = options_seen.find(option_table[i].short_option);
    if (pos == options_seen.end()) {
      CommandArgumentType arg_type = option_table[i].argument_type;
      const char *arg_name =
          SBCommandInterpreter::GetArgumentTypeAsCString(arg_type);

      options_seen.insert(option_table[i].short_option);
      fprintf(out, "%*s-%c ", indent_level, "", option_table[i].short_option);
      if (arg_type != eArgTypeNone)
        fprintf(out, "<%s>", arg_name);
      fprintf(out, "\n");
      fprintf(out, "%*s--%s ", indent_level, "", option_table[i].long_option);
      if (arg_type != eArgTypeNone)
        fprintf(out, "<%s>", arg_name);
      fprintf(out, "\n");
      indent_level += 5;
      OutputFormattedUsageText(out, indent_level, option_table[i].usage_text,
                               screen_width);
      indent_level -= 5;
      fprintf(out, "\n");
    }
  }

  indent_level -= 5;

  fprintf(out, "\n%*sNotes:\n", indent_level, "");
  indent_level += 5;

  fprintf(out,
          "\n%*sMultiple \"-s\" and \"-o\" options can be provided.  They will "
          "be processed"
          "\n%*sfrom left to right in order, with the source files and commands"
          "\n%*sinterleaved.  The same is true of the \"-S\" and \"-O\" "
          "options.  The before"
          "\n%*sfile and after file sets can intermixed freely, the command "
          "parser will"
          "\n%*ssort them out.  The order of the file specifiers (\"-c\", "
          "\"-f\", etc.) is"
          "\n%*snot significant in this regard.\n\n",
          indent_level, "", indent_level, "", indent_level, "", indent_level,
          "", indent_level, "", indent_level, "");

  fprintf(
      out,
      "\n%*sIf you don't provide -f then the first argument will be the file "
      "to be"
      "\n%*sdebugged which means that '%s -- <filename> [<ARG1> [<ARG2>]]' also"
      "\n%*sworks.  But remember to end the options with \"--\" if any of your"
      "\n%*sarguments have a \"-\" in them.\n\n",
      indent_level, "", indent_level, "", name, indent_level, "", indent_level,
      "");
}

void BuildGetOptTable(OptionDefinition *expanded_option_table,
                      std::vector<struct option> &getopt_table,
                      uint32_t num_options) {
  if (num_options == 0)
    return;

  uint32_t i;
  uint32_t j;
  std::bitset<256> option_seen;

  getopt_table.resize(num_options + 1);

  for (i = 0, j = 0; i < num_options; ++i) {
    char short_opt = expanded_option_table[i].short_option;

    if (option_seen.test(short_opt) == false) {
      getopt_table[j].name = expanded_option_table[i].long_option;
      getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
      getopt_table[j].flag = NULL;
      getopt_table[j].val = expanded_option_table[i].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(),
      m_after_crash_commands(), m_debug_mode(false), m_source_quietly(false),
      m_print_version(false), m_print_python_path(false), m_print_help(false),
      m_wait_for(false), m_repl(false), m_repl_lang(eLanguageTypeUnknown),
      m_repl_options(), m_process_name(),
      m_process_pid(LLDB_INVALID_PROCESS_ID), m_use_external_editor(false),
      m_batch(false), m_seen_options() {}

Driver::OptionData::~OptionData() {}

void Driver::OptionData::Clear() {
  m_args.clear();
  m_script_lang = lldb::eScriptLanguageDefault;
  m_initial_commands.clear();
  m_after_file_commands.clear();

  // If there is a local .lldbinit, add that to the
  // list of things to be sourced, if the settings
  // permit it.
  SBFileSpec local_lldbinit(".lldbinit", true);

  SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory();
  homedir_dot_lldb.AppendPathComponent(".lldbinit");

  // 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) {
    char path[2048];
    local_lldbinit.GetPath(path, 2047);
    InitialCmdEntry entry(path, true, true, true);
    m_after_file_commands.push_back(entry);
  }

  m_debug_mode = false;
  m_source_quietly = false;
  m_print_help = false;
  m_print_version = false;
  m_print_python_path = false;
  m_use_external_editor = false;
  m_wait_for = false;
  m_process_name.erase();
  m_batch = false;
  m_after_crash_commands.clear();

  m_process_pid = LLDB_INVALID_PROCESS_ID;
}

void Driver::OptionData::AddInitialCommand(const char *command,
                                           CommandPlacement placement,
                                           bool is_file, SBError &error) {
  std::vector<InitialCmdEntry> *command_set;
  switch (placement) {
  case eCommandPlacementBeforeFile:
    command_set = &(m_initial_commands);
    break;
  case eCommandPlacementAfterFile:
    command_set = &(m_after_file_commands);
    break;
  case eCommandPlacementAfterCrash:
    command_set = &(m_after_crash_commands);
    break;
  }

  if (is_file) {
    SBFileSpec file(command);
    if (file.Exists())
      command_set->push_back(InitialCmdEntry(command, is_file, false));
    else if (file.ResolveExecutableLocation()) {
      char final_path[PATH_MAX];
      file.GetPath(final_path, sizeof(final_path));
      command_set->push_back(InitialCmdEntry(final_path, is_file, false));
    } else
      error.SetErrorStringWithFormat(
          "file specified in --source (-s) option doesn't exist: '%s'", optarg);
  } else
    command_set->push_back(InitialCmdEntry(command, is_file, false));
}

void Driver::ResetOptionValues() { m_option_data.Clear(); }

const char *Driver::GetFilename() const {
  if (m_option_data.m_args.empty())
    return NULL;
  return m_option_data.m_args.front().c_str();
}

const char *Driver::GetCrashLogFilename() const {
  if (m_option_data.m_crash_log.empty())
    return NULL;
  return m_option_data.m_crash_log.c_str();
}

lldb::ScriptLanguage Driver::GetScriptLanguage() const {
  return m_option_data.m_script_lang;
}

void Driver::WriteCommandsForSourcing(CommandPlacement placement,
                                      SBStream &strm) {
  std::vector<OptionData::InitialCmdEntry> *command_set;
  switch (placement) {
  case eCommandPlacementBeforeFile:
    command_set = &m_option_data.m_initial_commands;
    break;
  case eCommandPlacementAfterFile:
    command_set = &m_option_data.m_after_file_commands;
    break;
  case eCommandPlacementAfterCrash:
    command_set = &m_option_data.m_after_crash_commands;
    break;
  }

  for (const auto &command_entry : *command_set) {
    const char *command = command_entry.contents.c_str();
    if (command_entry.is_file) {
      // If this command_entry is a file to be sourced, and it's the ./.lldbinit
      // file (the .lldbinit
      // file in the current working directory), only read it if
      // target.load-cwd-lldbinit is 'true'.
      if (command_entry.is_cwd_lldbinit_file_read) {
        SBStringList strlist = m_debugger.GetInternalVariableValue(
            "target.load-cwd-lldbinit", m_debugger.GetInstanceName());
        if (strlist.GetSize() == 1 &&
            strcmp(strlist.GetStringAtIndex(0), "warn") == 0) {
          FILE *output = m_debugger.GetOutputFileHandle();
          ::fprintf(
              output,
              "There is a .lldbinit file in the current directory which is not "
              "being read.\n"
              "To silence this warning without sourcing in the local "
              ".lldbinit,\n"
              "add the following to the lldbinit file in your home directory:\n"
              "    settings set target.load-cwd-lldbinit false\n"
              "To allow lldb to source .lldbinit files in the current working "
              "directory,\n"
              "set the value of this variable to true.  Only do so if you "
              "understand and\n"
              "accept the security risk.\n");
          return;
        }
        if (strlist.GetSize() == 1 &&
            strcmp(strlist.GetStringAtIndex(0), "false") == 0) {
          return;
        }
      }
      bool source_quietly =
          m_option_data.m_source_quietly || command_entry.source_quietly;
      strm.Printf("command source -s %i '%s'\n", source_quietly, command);
    } else
      strm.Printf("%s\n", command);
  }
}

bool Driver::GetDebugMode() const { return m_option_data.m_debug_mode; }

// Check the arguments that were passed to this program to make sure they are
// valid and to get their
// argument values (if any).  Return a boolean value indicating whether or not
// to start up the full
// debugger (i.e. the Command Interpreter) or not.  Return FALSE if the
// 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) {
  ResetOptionValues();

  SBCommandReturnObject result;

  SBError error;
  std::string option_string;
  struct option *long_options = NULL;
  std::vector<struct option> long_options_vector;
  uint32_t num_options;

  for (num_options = 0; g_options[num_options].long_option != NULL;
       ++num_options)
    /* Do Nothing. */;

  if (num_options == 0) {
    if (argc > 1)
      error.SetErrorStringWithFormat("invalid number of options");
    return error;
  }

  BuildGetOptTable(g_options, long_options_vector, num_options);

  if (long_options_vector.empty())
    long_options = NULL;
  else
    long_options = &long_options_vector.front();

  if (long_options == NULL) {
    error.SetErrorStringWithFormat("invalid long options");
    return error;
  }

  // Build the option_string argument for call to getopt_long_only.

  for (int i = 0; long_options[i].name != NULL; ++i) {
    if (long_options[i].flag == NULL) {
      option_string.push_back((char)long_options[i].val);
      switch (long_options[i].has_arg) {
      default:
      case no_argument:
        break;
      case required_argument:
        option_string.push_back(':');
        break;
      case optional_argument:
        option_string.append("::");
        break;
      }
    }
  }

  // This is kind of a pain, but since we make the debugger in the Driver's
  // constructor, we can't
  // know at that point whether we should read in init files yet.  So we don't
  // read them in in the
  // Driver constructor, then set the flags back to "read them in" here, and
  // then if we see the
  // "-n" flag, we'll turn it off again.  Finally we have to read them in by
  // hand later in the
  // main loop.

  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,
                             &long_options_index);

    if (val == -1)
      break;
    else if (val == '?') {
      m_option_data.m_print_help = true;
      error.SetErrorStringWithFormat("unknown or ambiguous option");
      break;
    } else if (val == 0)
      continue;
    else {
      m_option_data.m_seen_options.insert((char)val);
      if (long_options_index == -1) {
        for (int i = 0; long_options[i].name || long_options[i].has_arg ||
                        long_options[i].flag || long_options[i].val;
             ++i) {
          if (long_options[i].val == val) {
            long_options_index = i;
            break;
          }
        }
      }

      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 '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;
      }
    }
  }

  if (error.Fail() || m_option_data.m_print_help) {
    ShowUsage(out_fh, g_options, m_option_data);
    exiting = true;
  } else if (m_option_data.m_print_version) {
    ::fprintf(out_fh, "%s\n", m_debugger.GetVersionString());
    exiting = true;
  } else if (m_option_data.m_print_python_path) {
    SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
    if (python_file_spec.IsValid()) {
      char python_path[PATH_MAX];
      size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
      if (num_chars < PATH_MAX) {
        ::fprintf(out_fh, "%s\n", python_path);
      } else
        ::fprintf(out_fh, "<PATH TOO LONG>\n");
    } else
      ::fprintf(out_fh, "<COULD NOT FIND PATH>\n");
    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);
      }
    }

  } else {
    // Skip any options we consumed with getopt_long_only
    argc -= optind;

    if (argc > 0)
      ::fprintf(out_fh,
                "Warning: program arguments are ignored when attaching.\n");
  }

  return error;
}

static ::FILE *PrepareCommandsForSourcing(const char *commands_data,
                                          size_t commands_size, int fds[2]) {
  enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE

  ::FILE *commands_file = NULL;
  fds[0] = -1;
  fds[1] = -1;
  int err = 0;
#ifdef _WIN32
  err = _pipe(fds, commands_size, O_BINARY);
#else
  err = pipe(fds);
#endif
  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",
              fds[WRITE], static_cast<const void *>(commands_data),
              static_cast<uint64_t>(commands_size), errno);
    } else if (static_cast<size_t>(nrwr) == commands_size) {
// Close the write end of the pipe so when we give the read end to
// the debugger/command interpreter it will exit when it consumes all
// of the data
#ifdef _WIN32
      _close(fds[WRITE]);
      fds[WRITE] = -1;
#else
      close(fds[WRITE]);
      fds[WRITE] = -1;
#endif
      // Now open the read file descriptor in a FILE * that we can give to
      // 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".
      } else {
        fprintf(stderr, "error: fdopen(%i, \"r\") failed (errno = %i) when "
                        "trying to open LLDB commands pipe\n",
                fds[READ], errno);
      }
    }
  } else {
    fprintf(stderr,
            "error: can't create pipe file descriptors for LLDB commands\n");
  }

  return commands_file;
}

void CleanupAfterCommandSourcing(int fds[2]) {
  enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE

  // Close any pipes that we still have ownership of
  if (fds[WRITE] != -1) {
#ifdef _WIN32
    _close(fds[WRITE]);
    fds[WRITE] = -1;
#else
    close(fds[WRITE]);
    fds[WRITE] = -1;
#endif
  }

  if (fds[READ] != -1) {
#ifdef _WIN32
    _close(fds[READ]);
    fds[READ] = -1;
#else
    close(fds[READ]);
    fds[READ] = -1;
#endif
  }
}

std::string EscapeString(std::string arg) {
  std::string::size_type pos = 0;
  while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) {
    arg.insert(pos, 1, '\\');
    pos += 2;
  }
  return '"' + arg + '"';
}

int Driver::MainLoop() {
  if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) {
    g_old_stdin_termios_is_valid = true;
    atexit(reset_stdin_termios);
  }

#ifndef _MSC_VER
  // Disabling stdin buffering with MSVC's 2015 CRT exposes a bug in fgets
  // which causes it to miss newlines depending on whether there have been an
  // odd or even number of characters.  Bug has been reported to MS via Connect.
  ::setbuf(stdin, NULL);
#endif
  ::setbuf(stdout, NULL);

  m_debugger.SetErrorFileHandle(stderr, false);
  m_debugger.SetOutputFileHandle(stdout, false);
  m_debugger.SetInputFileHandle(stdin,
                                false); // Don't take ownership of STDIN yet...

  m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);

  struct winsize window_size;
  if (isatty(STDIN_FILENO) &&
      ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) {
    if (window_size.ws_col > 0)
      m_debugger.SetTerminalWidth(window_size.ws_col);
  }

  SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();

  // Before we handle any options from the command line, we parse the
  // .lldbinit file in the user's home directory.
  SBCommandReturnObject result;
  sb_interpreter.SourceInitFileInHomeDirectory(result);
  if (GetDebugMode()) {
    result.PutError(m_debugger.GetErrorFileHandle());
    result.PutOutput(m_debugger.GetOutputFileHandle());
  }

  // We allow the user to specify an exit code when calling quit which we will
  // return when exiting.
  m_debugger.GetCommandInterpreter().AllowExitCodeOnQuit(true);

  // Now we handle options we got from the command line
  SBStream commands_stream;

  // First source in the commands specified to be run before the file arguments
  // are processed.
  WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream);

  const size_t num_args = m_option_data.m_args.size();
  if (num_args > 0) {
    char arch_name[64];
    if (m_debugger.GetDefaultArchitecture(arch_name, sizeof(arch_name)))
      commands_stream.Printf("target create --arch=%s %s", arch_name,
                             EscapeString(m_option_data.m_args[0]).c_str());
    else
      commands_stream.Printf("target create %s",
                             EscapeString(m_option_data.m_args[0]).c_str());

    if (!m_option_data.m_core_file.empty()) {
      commands_stream.Printf(" --core %s",
                             EscapeString(m_option_data.m_core_file).c_str());
    }
    commands_stream.Printf("\n");

    if (num_args > 1) {
      commands_stream.Printf("settings set -- target.run-args ");
      for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
        commands_stream.Printf(
            " %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
      commands_stream.Printf("\n");
    }
  } else if (!m_option_data.m_core_file.empty()) {
    commands_stream.Printf("target create --core %s\n",
                           EscapeString(m_option_data.m_core_file).c_str());
  } else if (!m_option_data.m_process_name.empty()) {
    commands_stream.Printf("process attach --name %s",
                           EscapeString(m_option_data.m_process_name).c_str());

    if (m_option_data.m_wait_for)
      commands_stream.Printf(" --waitfor");

    commands_stream.Printf("\n");

  } else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid) {
    commands_stream.Printf("process attach --pid %" PRIu64 "\n",
                           m_option_data.m_process_pid);
  }

  WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);

  if (GetDebugMode()) {
    result.PutError(m_debugger.GetErrorFileHandle());
    result.PutOutput(m_debugger.GetOutputFileHandle());
  }

  bool handle_events = true;
  bool spawn_thread = false;

  if (m_option_data.m_repl) {
    const char *repl_options = NULL;
    if (!m_option_data.m_repl_options.empty())
      repl_options = m_option_data.m_repl_options.c_str();
    SBError error(m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
    if (error.Fail()) {
      const char *error_cstr = error.GetCString();
      if (error_cstr && error_cstr[0])
        fprintf(stderr, "error: %s\n", error_cstr);
      else
        fprintf(stderr, "error: %u\n", error.GetError());
    }
  } else {
    // Check if we have any data in the commands stream, and if so, save it to a
    // temp file
    // so we can then run the command interpreter using the file contents.
    const char *commands_data = commands_stream.GetData();
    const size_t commands_size = commands_stream.GetSize();

    // The command file might have requested that we quit, this variable will
    // track that.
    bool quit_requested = false;
    bool stopped_for_crash = false;
    if (commands_data && commands_size) {
      int initial_commands_fds[2];
      bool success = true;
      FILE *commands_file = PrepareCommandsForSourcing(
          commands_data, commands_size, initial_commands_fds);
      if (commands_file) {
        m_debugger.SetInputFileHandle(commands_file, true);

        // Set the debugger into Sync mode when running the command file.
        // Otherwise command files
        // that run the target won't run in a sensible way.
        bool old_async = m_debugger.GetAsync();
        m_debugger.SetAsync(false);
        int num_errors;

        SBCommandInterpreterRunOptions options;
        options.SetStopOnError(true);
        if (m_option_data.m_batch)
          options.SetStopOnCrash(true);

        m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options,
                                         num_errors, quit_requested,
                                         stopped_for_crash);

        if (m_option_data.m_batch && stopped_for_crash &&
            !m_option_data.m_after_crash_commands.empty()) {
          int crash_command_fds[2];
          SBStream crash_commands_stream;
          WriteCommandsForSourcing(eCommandPlacementAfterCrash,
                                   crash_commands_stream);
          const char *crash_commands_data = crash_commands_stream.GetData();
          const size_t crash_commands_size = crash_commands_stream.GetSize();
          commands_file = PrepareCommandsForSourcing(
              crash_commands_data, crash_commands_size, crash_command_fds);
          if (commands_file) {
            bool local_quit_requested;
            bool local_stopped_for_crash;
            m_debugger.SetInputFileHandle(commands_file, true);

            m_debugger.RunCommandInterpreter(
                handle_events, spawn_thread, options, num_errors,
                local_quit_requested, local_stopped_for_crash);
            if (local_quit_requested)
              quit_requested = true;
          }
        }
        m_debugger.SetAsync(old_async);
      } else
        success = false;

      // Close any pipes that we still have ownership of
      CleanupAfterCommandSourcing(initial_commands_fds);

      // Something went wrong with command pipe
      if (!success) {
        exit(1);
      }
    }

    // Now set the input file handle to STDIN and run the command
    // interpreter again in interactive mode and let the debugger
    // take ownership of stdin

    bool go_interactive = true;
    if (quit_requested)
      go_interactive = false;
    else if (m_option_data.m_batch && !stopped_for_crash)
      go_interactive = false;

    if (go_interactive) {
      m_debugger.SetInputFileHandle(stdin, true);
      m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
    }
  }

  reset_stdin_termios();
  fclose(stdin);

  int exit_code = sb_interpreter.GetQuitStatus();
  SBDebugger::Destroy(m_debugger);
  return exit_code;
}

void Driver::ResizeWindow(unsigned short col) {
  GetDebugger().SetTerminalWidth(col);
}

void sigwinch_handler(int signo) {
  struct winsize window_size;
  if (isatty(STDIN_FILENO) &&
      ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) {
    if ((window_size.ws_col > 0) && g_driver != NULL) {
      g_driver->ResizeWindow(window_size.ws_col);
    }
  }
}

void sigint_handler(int signo) {
  static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT;
  if (g_driver) {
    if (!g_interrupt_sent.test_and_set()) {
      g_driver->GetDebugger().DispatchInputInterrupt();
      g_interrupt_sent.clear();
      return;
    }
  }

  _exit(signo);
}

void sigtstp_handler(int signo) {
  if (g_driver)
    g_driver->GetDebugger().SaveInputTerminalState();

  signal(signo, SIG_DFL);
  kill(getpid(), signo);
  signal(signo, sigtstp_handler);
}

void sigcont_handler(int signo) {
  if (g_driver)
    g_driver->GetDebugger().RestoreInputTerminalState();

  signal(signo, SIG_DFL);
  kill(getpid(), signo);
  signal(signo, sigcont_handler);
}

int
#ifdef _MSC_VER
wmain(int argc, wchar_t const *wargv[])
#else
main(int argc, char const *argv[])
#endif
{
#ifdef _MSC_VER
  // Convert wide arguments to UTF-8
  std::vector<std::string> argvStrings(argc);
  std::vector<const char *> argvPointers(argc);
  for (int i = 0; i != argc; ++i) {
    llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
    argvPointers[i] = argvStrings[i].c_str();
  }
  const char **argv = argvPointers.data();
#endif

  llvm::StringRef ToolName = argv[0];
  llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
  llvm::PrettyStackTraceProgram X(argc, argv);

  SBDebugger::Initialize();

  SBHostOS::ThreadCreated("<lldb.driver.main-thread>");

  signal(SIGINT, sigint_handler);
#if !defined(_MSC_VER)
  signal(SIGPIPE, SIG_IGN);
  signal(SIGWINCH, sigwinch_handler);
  signal(SIGTSTP, sigtstp_handler);
  signal(SIGCONT, sigcont_handler);
#endif

  int exit_code = 0;
  // Create a scope for driver so that the driver object will destroy itself
  // before SBDebugger::Terminate() is called.
  {
    Driver driver;

    bool exiting = false;
    SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
    if (error.Fail()) {
      exit_code = 1;
      const char *error_cstr = error.GetCString();
      if (error_cstr)
        ::fprintf(stderr, "error: %s\n", error_cstr);
    } else if (!exiting) {
      exit_code = driver.MainLoop();
    }
  }

  SBDebugger::Terminate();
  return exit_code;
}
