//===-- CLIDebugger.cpp - Command Line Interface to the Debugger ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the main implementation of the Command Line Interface to
// the debugger.
//
//===----------------------------------------------------------------------===//

#include "CLIDebugger.h"
#include "CLICommand.h"
#include "llvm/Debugger/SourceFile.h"
#include "llvm/ADT/StringExtras.h"
#include <iostream>
using namespace llvm;

/// CLIDebugger constructor - This initializes the debugger to its default
/// state, and initializes the command table.
///
CLIDebugger::CLIDebugger()
  : TheProgramInfo(0), TheRuntimeInfo(0), Prompt("(llvm-db) "), ListSize(10) {
  // Initialize instance variables
  CurrentFile = 0;
  LineListedStart = 1;
  LineListedEnd = 1;
  LastCurrentFrame = 0;
  CurrentLanguage = 0;

  CLICommand *C;
  //===--------------------------------------------------------------------===//
  // Program startup and shutdown options
  //
  addCommand("file", new BuiltinCLICommand(
    "Use specified file as the program to be debugged",
    "The debugger looks in the current directory and the program $PATH for the"
    " specified LLVM program.  It then unloads the currently loaded program and"
    " loads the specified program.\n",
    &CLIDebugger::fileCommand));

  addCommand("create", new BuiltinCLICommand(
    "Start the program, halting its execution in main",
    "This command creates an instance of the current program, but stops"
    "\nexecution immediately.\n",
    &CLIDebugger::createCommand));

  addCommand("kill", new BuiltinCLICommand(
    "Kills the execution of the current program being debugged", "",
    &CLIDebugger::killCommand));

  addCommand("quit", new BuiltinCLICommand(
    "Exit the debugger", "",
    &CLIDebugger::quitCommand));

  //===--------------------------------------------------------------------===//
  // Program execution commands
  //
  addCommand("run", C = new BuiltinCLICommand(
    "Start the program running from the beginning", "",
    &CLIDebugger::runCommand));
  addCommand("r", C);

  addCommand("cont", C = new BuiltinCLICommand(
    "Continue program being debugged until the next stop point", "",
    &CLIDebugger::contCommand));
  addCommand("c", C); addCommand("fg", C);

  addCommand("step", C = new BuiltinCLICommand(
    "Step program until it reaches a new source line", "",
    &CLIDebugger::stepCommand));
  addCommand("s", C);

  addCommand("next", C = new BuiltinCLICommand(
    "Step program until it reaches a new source line, stepping over calls", "",
    &CLIDebugger::nextCommand));
  addCommand("n", C);

  addCommand("finish", new BuiltinCLICommand(
    "Execute until the selected stack frame returns",
   "Upon return, the value returned is printed and put in the value history.\n",
    &CLIDebugger::finishCommand));

  //===--------------------------------------------------------------------===//
  // Stack frame commands
  //
  addCommand("backtrace", C = new BuiltinCLICommand(
   "Print backtrace of all stack frames, or innermost COUNT frames",
   "FIXME: describe.  Takes 'n', '-n' or 'full'\n",
    &CLIDebugger::backtraceCommand));
  addCommand("bt", C);

  addCommand("up", new BuiltinCLICommand(
    "Select and print stack frame that called this one",
    "An argument says how many frames up to go.\n",
    &CLIDebugger::upCommand));

  addCommand("down", new BuiltinCLICommand(
    "Select and print stack frame called by this one",
    "An argument says how many frames down go.\n",
    &CLIDebugger::downCommand));

  addCommand("frame", C = new BuiltinCLICommand(
    "Select and print a stack frame",
 "With no argument, print the selected stack frame.  (See also 'info frame').\n"
 "An argument specifies the frame to select.\n",
    &CLIDebugger::frameCommand));
  addCommand("f", C);

  //===--------------------------------------------------------------------===//
  // Breakpoint related commands
  //
  addCommand("break", C = new BuiltinCLICommand(
   "Set breakpoint at specified line or function",
   "FIXME: describe.\n",
    &CLIDebugger::breakCommand));
  addCommand("b", C);


  //===--------------------------------------------------------------------===//
  // Miscellaneous commands
  //
  addCommand("info", new BuiltinCLICommand(
    "Generic command for showing things about the program being debugged",
    "info functions: display information about functions in the program.\ninfo"
    " source : display information about the current source file.\ninfo source"
    "s : Display source file names for the program\ninfo target : print status"
    " of inferior process\n",
    &CLIDebugger::infoCommand));

  addCommand("list", C = new BuiltinCLICommand(
    "List specified function or line",
    "FIXME: document\n",
    &CLIDebugger::listCommand));
  addCommand("l", C);

  addCommand("set", new BuiltinCLICommand(
    "Change program or debugger variable",
    "FIXME: document\n",
    &CLIDebugger::setCommand));

  addCommand("show", new BuiltinCLICommand(
    "Generic command for showing things about the debugger",
    "FIXME: document\n",
    &CLIDebugger::showCommand));

  addCommand("help", C = new BuiltinCLICommand(
    "Prints information about available commands", "",
    &CLIDebugger::helpCommand));
  addCommand("h", C);
}


/// addCommand - Add a command to the CommandTable, potentially displacing a
/// preexisting command.
void CLIDebugger::addCommand(const std::string &Option, CLICommand *Cmd) {
  assert(Cmd && "Cannot set a null command!");
  CLICommand *&CS = CommandTable[Option];
  if (CS == Cmd) return; // noop

  // If we already have a command, decrement the command's reference count.
  if (CS) {
    CS->removeOptionName(Option);
    CS->dropRef();
  }
  CS = Cmd;

  // Remember that we are using this command.
  Cmd->addRef();
  Cmd->addOptionName(Option);
}

static bool isValidPrefix(const std::string &Prefix, const std::string &Option){
  return Prefix.size() <= Option.size() &&
         Prefix == std::string(Option.begin(), Option.begin()+Prefix.size());
}

/// getCommand - This looks up the specified command using a fuzzy match.
/// If the string exactly matches a command or is an unambiguous prefix of a
/// command, it returns the command.  Otherwise it throws an exception
/// indicating the possible ambiguous choices.
CLICommand *CLIDebugger::getCommand(const std::string &Command) {

  // Look up the command in the table.
  std::map<std::string, CLICommand*>::iterator CI =
    CommandTable.lower_bound(Command);

  if (Command == "") {
    throw "Null command should not get here!";
  } else if (CI == CommandTable.end() ||
             !isValidPrefix(Command, CI->first)) {
    // If this command has no relation to anything in the command table,
    // print the error message.
    throw "Unknown command: '" + Command +
          "'.  Use 'help' for list of commands.";
  } else if (CI->first == Command) {
    // We have an exact match on the command
    return CI->second;
  } else {
    // Otherwise, we have a prefix match.  Check to see if this is
    // unambiguous, and if so, run it.
    std::map<std::string, CLICommand*>::iterator CI2 = CI;

    // If the next command is a valid completion of this one, we are
    // ambiguous.
    if (++CI2 != CommandTable.end() && isValidPrefix(Command, CI2->first)) {
      std::string ErrorMsg =
        "Ambiguous command '" + Command + "'.  Options: " + CI->first;
      for (++CI; CI != CommandTable.end() &&
             isValidPrefix(Command, CI->first); ++CI)
        ErrorMsg += ", " + CI->first;
      throw ErrorMsg;
    } else {
      // It's an unambiguous prefix of a command, use it.
      return CI->second;
    }
  }
}


/// run - Start the debugger, returning when the user exits the debugger.  This
/// starts the main event loop of the CLI debugger.
///
int CLIDebugger::run() {
  std::string Command;
  std::cout << Prompt;

  // Keep track of the last command issued, so that we can reissue it if the
  // user hits enter as the command.
  CLICommand *LastCommand = 0;
  std::string LastArgs;

  // Continue reading commands until the end of file.
  while (getline(std::cin, Command)) {
    std::string Arguments = Command;

    // Split off the command from the arguments to the command.
    Command = getToken(Arguments, " \t\n\v\f\r\\/;.*&");

    try {
      CLICommand *CurCommand;

      if (Command == "") {
        CurCommand = LastCommand;
        Arguments = LastArgs;
      } else {
        CurCommand = getCommand(Command);
      }

      // Save the command we are running in case the user wants us to repeat it
      // next time.
      LastCommand = CurCommand;
      LastArgs = Arguments;

      // Finally, execute the command.
      if (CurCommand)
        CurCommand->runCommand(*this, Arguments);

    } catch (int RetVal) {
      // The quit command exits the command loop by throwing an integer return
      // code.
      return RetVal;
    } catch (const std::string &Error) {
      std::cout << "Error: " << Error << "\n";
    } catch (const char *Error) {
      std::cout << "Error: " << Error << "\n";
    } catch (const NonErrorException &E) {
      std::cout << E.getMessage() << "\n";
    } catch (...) {
      std::cout << "ERROR: Debugger caught unexpected exception!\n";
      // Attempt to continue.
    }

    // Write the prompt to get the next bit of user input
    std::cout << Prompt;
  }

  return 0;
}


/// askYesNo - Ask the user a question, and demand a yes/no response.  If
/// the user says yes, return true.
///
bool CLIDebugger::askYesNo(const std::string &Message) const {
  std::string Answer;
  std::cout << Message << " (y or n) " << std::flush;
  while (getline(std::cin, Answer)) {
    std::string Val = getToken(Answer);
    if (getToken(Answer).empty()) {
      if (Val == "yes" || Val == "y" || Val == "YES" || Val == "Y" ||
          Val == "Yes")
        return true;
      if (Val == "no" || Val == "n" || Val == "NO" || Val == "N" ||
          Val == "No")
        return false;
    }

    std::cout << "Please answer y or n.\n" << Message << " (y or n) "
              << std::flush;
  }

  // Ran out of input?
  return false;
}
