//===-- Commands.cpp - Implement various commands for the CLI -------------===//
//
//                     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 implements many builtin user commands.
//
//===----------------------------------------------------------------------===//

#include "CLIDebugger.h"
#include "CLICommand.h"
#include "llvm/Debugger/ProgramInfo.h"
#include "llvm/Debugger/RuntimeInfo.h"
#include "llvm/Debugger/SourceLanguage.h"
#include "llvm/Debugger/SourceFile.h"
#include "llvm/Debugger/InferiorProcess.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/ADT/StringExtras.h"
#include <iostream>
using namespace llvm;

/// getCurrentLanguage - Return the current source language that the user is
/// playing around with.  This is aquired from the current stack frame of a
/// running program if one exists, but this value can be explicitly set by the
/// user as well.
const SourceLanguage &CLIDebugger::getCurrentLanguage() const {
  // If the user explicitly switched languages with 'set language', use what
  // they asked for.
  if (CurrentLanguage) {
    return *CurrentLanguage;
  } else if (Dbg.isProgramRunning()) {
    // Otherwise, if the program is running, infer the current language from it.
    const GlobalVariable *FuncDesc =
      getRuntimeInfo().getCurrentFrame().getFunctionDesc();
    return getProgramInfo().getFunction(FuncDesc).getSourceFile().getLanguage();
  } else {
    // Otherwise, default to C like GDB apparently does.
    return SourceLanguage::getCFamilyInstance();
  }
}

/// startProgramRunning - If the program has been updated, reload it, then
/// start executing the program.
void CLIDebugger::startProgramRunning() {
  eliminateRunInfo();

  // If the program has been modified, reload it!
  sys::PathWithStatus Program(Dbg.getProgramPath());
  std::string Err;
  const sys::FileStatus *Status = Program.getFileStatus(false, &Err);
  if (!Status)
    throw Err;
  if (TheProgramInfo->getProgramTimeStamp() != Status->getTimestamp()) {
    std::cout << "'" << Program << "' has changed; re-reading program.\n";

    // Unload an existing program.  This kills the program if necessary.
    Dbg.unloadProgram();
    delete TheProgramInfo;
    TheProgramInfo = 0;
    CurrentFile = 0;

    Dbg.loadProgram(Program.toString());
    TheProgramInfo = new ProgramInfo(Dbg.getProgram());
  }

  std::cout << "Starting program: " << Dbg.getProgramPath() << "\n";
  Dbg.createProgram();

  // There was no current frame.
  LastCurrentFrame = 0;
}

/// printSourceLine - Print the specified line of the current source file.
/// If the specified line is invalid (the source file could not be loaded or
/// the line number is out of range), don't print anything, but return true.
bool CLIDebugger::printSourceLine(unsigned LineNo) {
  assert(CurrentFile && "There is no current source file to print!");
  const char *LineStart, *LineEnd;
  CurrentFile->getSourceLine(LineNo-1, LineStart, LineEnd);
  if (LineStart == 0) return true;
  std::cout << LineNo;

  // If this is the line the program is currently stopped at, print a marker.
  if (Dbg.isProgramRunning()) {
    unsigned CurLineNo, CurColNo;
    const SourceFileInfo *CurSFI;
    getRuntimeInfo().getCurrentFrame().getSourceLocation(CurLineNo, CurColNo,
                                                         CurSFI);

    if (CurLineNo == LineNo && CurrentFile == &CurSFI->getSourceText())
      std::cout << " ->";
  }

  std::cout << "\t" << std::string(LineStart, LineEnd) << "\n";
  return false;
}

/// printProgramLocation - Print a line of the place where the current stack
/// frame has stopped and the source line it is on.
///
void CLIDebugger::printProgramLocation(bool PrintLocation) {
  assert(Dbg.isProgramLoaded() && Dbg.isProgramRunning() &&
         "Error program is not loaded and running!");

  // Figure out where the program stopped...
  StackFrame &SF = getRuntimeInfo().getCurrentFrame();
  unsigned LineNo, ColNo;
  const SourceFileInfo *FileDesc;
  SF.getSourceLocation(LineNo, ColNo, FileDesc);

  // If requested, print out some program information about WHERE we are.
  if (PrintLocation) {
    // FIXME: print the current function arguments
    if (const GlobalVariable *FuncDesc = SF.getFunctionDesc())
      std::cout << getProgramInfo().getFunction(FuncDesc).getSymbolicName();
    else
      std::cout << "<unknown function>";

    CurrentFile = &FileDesc->getSourceText();

    std::cout << " at " << CurrentFile->getFilename() << ":" << LineNo;
    if (ColNo) std::cout << ":" << ColNo;
    std::cout << "\n";
  }

  if (printSourceLine(LineNo))
    std::cout << "<could not load source file>\n";
  else {
    LineListedStart = LineNo-ListSize/2+1;
    if ((int)LineListedStart < 1) LineListedStart = 1;
    LineListedEnd = LineListedStart+1;
  }
}

/// eliminateRunInfo - We are about to run the program.  Forget any state
/// about how the program used to be stopped.
void CLIDebugger::eliminateRunInfo() {
  delete TheRuntimeInfo;
  TheRuntimeInfo = 0;
}

/// programStoppedSuccessfully - This method updates internal data
/// structures to reflect the fact that the program just executed a while,
/// and has successfully stopped.
void CLIDebugger::programStoppedSuccessfully() {
  assert(TheRuntimeInfo==0 && "Someone forgot to release the old RuntimeInfo!");

  TheRuntimeInfo = new RuntimeInfo(TheProgramInfo, Dbg.getRunningProcess());

  // FIXME: if there are any breakpoints at the current location, print them as
  // well.

  // Since the program as successfully stopped, print its location.
  void *CurrentFrame = getRuntimeInfo().getCurrentFrame().getFrameID();
  printProgramLocation(CurrentFrame != LastCurrentFrame);
  LastCurrentFrame = CurrentFrame;
}



/// getUnsignedIntegerOption - Get an unsigned integer number from the Val
/// string.  Check to make sure that the string contains an unsigned integer
/// token, and if not, throw an exception.  If isOnlyOption is set, also throw
/// an exception if there is extra junk at the end of the string.
static unsigned getUnsignedIntegerOption(const char *Msg, std::string &Val,
                                         bool isOnlyOption = true) {
  std::string Tok = getToken(Val);
  if (Tok.empty() || (isOnlyOption && !getToken(Val).empty()))
    throw std::string(Msg) + " expects an unsigned integer argument.";

  char *EndPtr;
  unsigned Result = strtoul(Tok.c_str(), &EndPtr, 0);
  if (EndPtr != Tok.c_str()+Tok.size())
    throw std::string(Msg) + " expects an unsigned integer argument.";

  return Result;
}

/// getOptionalUnsignedIntegerOption - This method is just like
/// getUnsignedIntegerOption, but if the argument value is not specified, a
/// default is returned instead of causing an error.
static unsigned
getOptionalUnsignedIntegerOption(const char *Msg, unsigned Default,
                                 std::string &Val, bool isOnlyOption = true) {
  // Check to see if the value was specified...
  std::string TokVal = getToken(Val);
  if (TokVal.empty()) return Default;

  // If it was specified, add it back to the value we are parsing...
  Val = TokVal+Val;

  // And parse normally.
  return getUnsignedIntegerOption(Msg, Val, isOnlyOption);
}


/// parseProgramOptions - This method parses the Options string and loads it
/// as options to be passed to the program.  This is used by the run command
/// and by 'set args'.
void CLIDebugger::parseProgramOptions(std::string &Options) {
  // FIXME: tokenizing by whitespace is clearly incorrect.  Instead we should
  // honor quotes and other things that a shell would.  Also in the future we
  // should support redirection of standard IO.

  std::vector<std::string> Arguments;
  for (std::string A = getToken(Options); !A.empty(); A = getToken(Options))
    Arguments.push_back(A);
  Dbg.setProgramArguments(Arguments.begin(), Arguments.end());
}


//===----------------------------------------------------------------------===//
//                   Program startup and shutdown options
//===----------------------------------------------------------------------===//


/// file command - If the user specifies an option, search the PATH for the
/// specified program/bitcode file and load it.  If the user does not specify
/// an option, unload the current program.
void CLIDebugger::fileCommand(std::string &Options) {
  std::string Prog = getToken(Options);
  if (!getToken(Options).empty())
    throw "file command takes at most one argument.";

  // Check to make sure the user knows what they are doing
  if (Dbg.isProgramRunning() &&
      !askYesNo("A program is already loaded.  Kill it?"))
    return;

  // Unload an existing program.  This kills the program if necessary.
  eliminateRunInfo();
  delete TheProgramInfo;
  TheProgramInfo = 0;
  Dbg.unloadProgram();
  CurrentFile = 0;

  // If requested, start the new program.
  if (Prog.empty()) {
    std::cout << "Unloaded program.\n";
  } else {
    std::cout << "Loading program... " << std::flush;
    Dbg.loadProgram(Prog);
    assert(Dbg.isProgramLoaded() &&
           "loadProgram succeeded, but not program loaded!");
    TheProgramInfo = new ProgramInfo(Dbg.getProgram());
    std::cout << "successfully loaded '" << Dbg.getProgramPath() << "'!\n";
  }
}


void CLIDebugger::createCommand(std::string &Options) {
  if (!getToken(Options).empty())
    throw "create command does not take any arguments.";
  if (!Dbg.isProgramLoaded()) throw "No program loaded.";
  if (Dbg.isProgramRunning() &&
      !askYesNo("The program is already running.  Restart from the beginning?"))
    return;

  // Start the program running.
  startProgramRunning();

  // The program stopped!
  programStoppedSuccessfully();
}

void CLIDebugger::killCommand(std::string &Options) {
  if (!getToken(Options).empty())
    throw "kill command does not take any arguments.";
  if (!Dbg.isProgramRunning())
    throw "No program is currently being run.";

  if (askYesNo("Kill the program being debugged?"))
    Dbg.killProgram();
  eliminateRunInfo();
}

void CLIDebugger::quitCommand(std::string &Options) {
  if (!getToken(Options).empty())
    throw "quit command does not take any arguments.";

  if (Dbg.isProgramRunning() &&
      !askYesNo("The program is running.  Exit anyway?"))
    return;

  // Throw exception to get out of the user-input loop.
  throw 0;
}


//===----------------------------------------------------------------------===//
//                        Program execution commands
//===----------------------------------------------------------------------===//

void CLIDebugger::runCommand(std::string &Options) {
  if (!Dbg.isProgramLoaded()) throw "No program loaded.";
  if (Dbg.isProgramRunning() &&
      !askYesNo("The program is already running.  Restart from the beginning?"))
    return;

  // Parse all of the options to the run command, which specify program
  // arguments to run with.
  parseProgramOptions(Options);

  eliminateRunInfo();

  // Start the program running.
  startProgramRunning();

  // Start the program running...
  Options = "";
  contCommand(Options);
}

void CLIDebugger::contCommand(std::string &Options) {
  if (!getToken(Options).empty()) throw "cont argument not supported yet.";
  if (!Dbg.isProgramRunning()) throw "Program is not running.";

  eliminateRunInfo();

  Dbg.contProgram();

  // The program stopped!
  programStoppedSuccessfully();
}

void CLIDebugger::stepCommand(std::string &Options) {
  if (!Dbg.isProgramRunning()) throw "Program is not running.";

  // Figure out how many times to step.
  unsigned Amount =
    getOptionalUnsignedIntegerOption("'step' command", 1, Options);

  eliminateRunInfo();

  // Step the specified number of times.
  for (; Amount; --Amount)
    Dbg.stepProgram();

  // The program stopped!
  programStoppedSuccessfully();
}

void CLIDebugger::nextCommand(std::string &Options) {
  if (!Dbg.isProgramRunning()) throw "Program is not running.";
  unsigned Amount =
    getOptionalUnsignedIntegerOption("'next' command", 1, Options);

  eliminateRunInfo();

  for (; Amount; --Amount)
    Dbg.nextProgram();

  // The program stopped!
  programStoppedSuccessfully();
}

void CLIDebugger::finishCommand(std::string &Options) {
  if (!getToken(Options).empty())
    throw "finish command does not take any arguments.";
  if (!Dbg.isProgramRunning()) throw "Program is not running.";

  // Figure out where we are exactly.  If the user requests that we return from
  // a frame that is not the top frame, make sure we get it.
  void *CurrentFrame = getRuntimeInfo().getCurrentFrame().getFrameID();

  eliminateRunInfo();

  Dbg.finishProgram(CurrentFrame);

  // The program stopped!
  programStoppedSuccessfully();
}

//===----------------------------------------------------------------------===//
//                           Stack frame commands
//===----------------------------------------------------------------------===//

void CLIDebugger::backtraceCommand(std::string &Options) {
  // Accepts "full", n, -n
  if (!getToken(Options).empty())
    throw "FIXME: bt command argument not implemented yet!";

  RuntimeInfo &RI = getRuntimeInfo();
  ProgramInfo &PI = getProgramInfo();

  try {
    for (unsigned i = 0; ; ++i) {
      StackFrame &SF = RI.getStackFrame(i);
      std::cout << "#" << i;
      if (i == RI.getCurrentFrameIdx())
        std::cout << " ->";
      std::cout << "\t" << SF.getFrameID() << " in ";
      if (const GlobalVariable *G = SF.getFunctionDesc())
        std::cout << PI.getFunction(G).getSymbolicName();

      unsigned LineNo, ColNo;
      const SourceFileInfo *SFI;
      SF.getSourceLocation(LineNo, ColNo, SFI);
      if (!SFI->getBaseName().empty()) {
        std::cout << " at " << SFI->getBaseName();
        if (LineNo) {
          std::cout << ":" << LineNo;
          if (ColNo)
            std::cout << ":" << ColNo;
        }
      }

      // FIXME: when we support shared libraries, we should print ' from foo.so'
      // if the stack frame is from a different object than the current one.

      std::cout << "\n";
    }
  } catch (...) {
    // Stop automatically when we run off the bottom of the stack.
  }
}

void CLIDebugger::upCommand(std::string &Options) {
  unsigned Num =
    getOptionalUnsignedIntegerOption("'up' command", 1, Options);

  RuntimeInfo &RI = getRuntimeInfo();
  unsigned CurFrame = RI.getCurrentFrameIdx();

  // Check to see if we go can up the specified number of frames.
  try {
    RI.getStackFrame(CurFrame+Num);
  } catch (...) {
    if (Num == 1)
      throw "Initial frame selected; you cannot go up.";
    else
      throw "Cannot go up " + utostr(Num) + " frames!";
  }

  RI.setCurrentFrameIdx(CurFrame+Num);
  printProgramLocation();
}

void CLIDebugger::downCommand(std::string &Options) {
  unsigned Num =
    getOptionalUnsignedIntegerOption("'down' command", 1, Options);

  RuntimeInfo &RI = getRuntimeInfo();
  unsigned CurFrame = RI.getCurrentFrameIdx();

  // Check to see if we can go up the specified number of frames.
  if (CurFrame < Num)
    if (Num == 1)
      throw "Bottom (i.e., innermost) frame selected; you cannot go down.";
    else
      throw "Cannot go down " + utostr(Num) + " frames!";

  RI.setCurrentFrameIdx(CurFrame-Num);
  printProgramLocation();
}

void CLIDebugger::frameCommand(std::string &Options) {
  RuntimeInfo &RI = getRuntimeInfo();
  unsigned CurFrame = RI.getCurrentFrameIdx();

  unsigned Num =
    getOptionalUnsignedIntegerOption("'frame' command", CurFrame, Options);

  // Check to see if we go to the specified frame.
  RI.getStackFrame(Num);

  RI.setCurrentFrameIdx(Num);
  printProgramLocation();
}


//===----------------------------------------------------------------------===//
//                        Breakpoint related commands
//===----------------------------------------------------------------------===//

void CLIDebugger::breakCommand(std::string &Options) {
  // Figure out where the user wants a breakpoint.
  const SourceFile *File;
  unsigned LineNo;

  // Check to see if the user specified a line specifier.
  std::string Option = getToken(Options);  // strip whitespace
  if (!Option.empty()) {
    Options = Option + Options;  // reconstruct string

    // Parse the line specifier.
    parseLineSpec(Options, File, LineNo);
  } else {
    // Build a line specifier for the current stack frame.
    throw "FIXME: breaking at the current location is not implemented yet!";
  }

  if (!File) File = CurrentFile;
  if (File == 0)
    throw "Unknown file to place breakpoint!";

  std::cerr << "Break: " << File->getFilename() << ":" << LineNo << "\n";

  throw "breakpoints not implemented yet!";
}

//===----------------------------------------------------------------------===//
//                          Miscellaneous commands
//===----------------------------------------------------------------------===//

void CLIDebugger::infoCommand(std::string &Options) {
  std::string What = getToken(Options);

  if (What.empty() || !getToken(Options).empty()){
    std::string infoStr("info");
    helpCommand(infoStr);
    return;
  }

  if (What == "frame") {
  } else if (What == "functions") {
    const std::map<const GlobalVariable*, SourceFunctionInfo*> &Functions
      = getProgramInfo().getSourceFunctions();
    std::cout << "All defined functions:\n";
    // FIXME: GDB groups these by source file.  We could do that I guess.
    for (std::map<const GlobalVariable*, SourceFunctionInfo*>::const_iterator
           I = Functions.begin(), E = Functions.end(); I != E; ++I) {
      std::cout << I->second->getSymbolicName() << "\n";
    }

  } else if (What == "source") {
    if (CurrentFile == 0)
      throw "No current source file.";

    // Get the SourceFile information for the current file.
    const SourceFileInfo &SF =
      getProgramInfo().getSourceFile(CurrentFile->getDescriptor());

    std::cout << "Current source file is: " << SF.getBaseName() << "\n"
              << "Compilation directory is: " << SF.getDirectory() << "\n";
    if (unsigned NL = CurrentFile->getNumLines())
      std::cout << "Located in: " << CurrentFile->getFilename() << "\n"
                << "Contains " << NL << " lines\n";
    else
      std::cout << "Could not find source file.\n";
    std::cout << "Source language is "
              << SF.getLanguage().getSourceLanguageName() << "\n";

  } else if (What == "sources") {
    const std::map<const GlobalVariable*, SourceFileInfo*> &SourceFiles =
      getProgramInfo().getSourceFiles();
    std::cout << "Source files for the program:\n";
    for (std::map<const GlobalVariable*, SourceFileInfo*>::const_iterator I =
           SourceFiles.begin(), E = SourceFiles.end(); I != E;) {
      std::cout << I->second->getDirectory() << "/"
                << I->second->getBaseName();
      ++I;
      if (I != E) std::cout << ", ";
    }
    std::cout << "\n";
  } else if (What == "target") {
    std::cout << Dbg.getRunningProcess().getStatus();
  } else {
    // See if this is something handled by the current language.
    if (getCurrentLanguage().printInfo(What))
      return;

    throw "Unknown info command '" + What + "'.  Try 'help info'.";
  }
}

/// parseLineSpec - Parses a line specifier, for use by the 'list' command.
/// If SourceFile is returned as a void pointer, then it was not specified.
/// If the line specifier is invalid, an exception is thrown.
void CLIDebugger::parseLineSpec(std::string &LineSpec,
                                const SourceFile *&SourceFile,
                                unsigned &LineNo) {
  SourceFile = 0;
  LineNo = 0;

  // First, check to see if we have a : separator.
  std::string FirstPart = getToken(LineSpec, ":");
  std::string SecondPart = getToken(LineSpec, ":");
  if (!getToken(LineSpec).empty()) throw "Malformed line specification!";

  // If there is no second part, we must have either "function", "number",
  // "+offset", or "-offset".
  if (SecondPart.empty()) {
    if (FirstPart.empty()) throw "Malformed line specification!";
    if (FirstPart[0] == '+') {
      FirstPart.erase(FirstPart.begin(), FirstPart.begin()+1);
      // For +n, return LineListedEnd+n
      LineNo = LineListedEnd +
               getUnsignedIntegerOption("Line specifier '+'", FirstPart);

    } else if (FirstPart[0] == '-') {
      FirstPart.erase(FirstPart.begin(), FirstPart.begin()+1);
      // For -n, return LineListedEnd-n
      LineNo = LineListedEnd -
               getUnsignedIntegerOption("Line specifier '-'", FirstPart);
      if ((int)LineNo < 1) LineNo = 1;
    } else if (FirstPart[0] == '*') {
      throw "Address expressions not supported as source locations!";
    } else {
      // Ok, check to see if this is just a line number.
      std::string Saved = FirstPart;
      try {
        LineNo = getUnsignedIntegerOption("", Saved);
      } catch (...) {
        // Ok, it's not a valid line number.  It must be a source-language
        // entity name.
        std::string Name = getToken(FirstPart);
        if (!getToken(FirstPart).empty())
          throw "Extra junk in line specifier after '" + Name + "'.";
        SourceFunctionInfo *SFI =
          getCurrentLanguage().lookupFunction(Name, getProgramInfo(),
                                              TheRuntimeInfo);
        if (SFI == 0)
          throw "Unknown identifier '" + Name + "'.";

        unsigned L, C;
        SFI->getSourceLocation(L, C);
        if (L == 0) throw "Could not locate '" + Name + "'!";
        LineNo = L;
        SourceFile = &SFI->getSourceFile().getSourceText();
        return;
      }
    }

  } else {
    // Ok, this must be a filename qualified line number or function name.
    // First, figure out the source filename.
    std::string SourceFilename = getToken(FirstPart);
    if (!getToken(FirstPart).empty())
      throw "Invalid filename qualified source location!";

    // Next, check to see if this is just a line number.
    std::string Saved = SecondPart;
    try {
      LineNo = getUnsignedIntegerOption("", Saved);
    } catch (...) {
      // Ok, it's not a valid line number.  It must be a function name.
      throw "FIXME: Filename qualified function names are not support "
            "as line specifiers yet!";
    }

    // Ok, we got the line number.  Now check out the source file name to make
    // sure it's all good.  If it is, return it.  If not, throw exception.
    SourceFile =&getProgramInfo().getSourceFile(SourceFilename).getSourceText();
  }
}

void CLIDebugger::listCommand(std::string &Options) {
  if (!Dbg.isProgramLoaded())
    throw "No program is loaded.  Use the 'file' command.";

  // Handle "list foo," correctly, by returning " " as the second token
  Options += " ";

  std::string FirstLineSpec = getToken(Options, ",");
  std::string SecondLineSpec = getToken(Options, ",");
  if (!getToken(Options, ",").empty())
    throw "list command only expects two source location specifiers!";

  // StartLine, EndLine - The starting and ending line numbers to print.
  unsigned StartLine = 0, EndLine = 0;

  if (SecondLineSpec.empty()) {    // No second line specifier provided?
    // Handle special forms like "", "+", "-", etc.
    std::string TmpSpec = FirstLineSpec;
    std::string Tok = getToken(TmpSpec);
    if (getToken(TmpSpec).empty() && (Tok == "" || Tok == "+" || Tok == "-")) {
      if (Tok == "+" || Tok == "") {
        StartLine = LineListedEnd;
        EndLine = StartLine + ListSize;
      } else {
        assert(Tok == "-");
        StartLine = LineListedStart-ListSize;
        EndLine = LineListedStart;
        if ((int)StartLine <= 0) StartLine = 1;
      }
    } else {
      // Must be a normal line specifier.
      const SourceFile *File;
      unsigned LineNo;
      parseLineSpec(FirstLineSpec, File, LineNo);

      // If the user only specified one file specifier, we should display
      // ListSize lines centered at the specified line.
      if (File != 0) CurrentFile = File;
      StartLine = LineNo - (ListSize+1)/2;
      if ((int)StartLine <= 0) StartLine = 1;
      EndLine = StartLine + ListSize;
    }

  } else {
    // Parse two line specifiers...
    const SourceFile *StartFile, *EndFile;
    unsigned StartLineNo, EndLineNo;
    parseLineSpec(FirstLineSpec, StartFile, StartLineNo);
    unsigned SavedLLE = LineListedEnd;
    LineListedEnd = StartLineNo;
    try {
      parseLineSpec(SecondLineSpec, EndFile, EndLineNo);
    } catch (...) {
      LineListedEnd = SavedLLE;
      throw;
    }

    // Inherit file specified by the first line spec if there was one.
    if (EndFile == 0) EndFile = StartFile;

    if (StartFile != EndFile)
      throw "Start and end line specifiers are in different files!";
    CurrentFile = StartFile;
    StartLine = StartLineNo;
    EndLine = EndLineNo+1;
  }

  assert((int)StartLine > 0 && (int)EndLine > 0 && StartLine <= EndLine &&
         "Error reading line specifiers!");

  // If there was no current file, and the user didn't specify one to list, we
  // have an error.
  if (CurrentFile == 0)
    throw "There is no current file to list.";

  // Remember for next time.
  LineListedStart = StartLine;
  LineListedEnd = StartLine;

  for (unsigned LineNo = StartLine; LineNo != EndLine; ++LineNo) {
    // Print the source line, unless it is invalid.
    if (printSourceLine(LineNo))
      break;
    LineListedEnd = LineNo+1;
  }

  // If we didn't print any lines, find out why.
  if (LineListedEnd == StartLine) {
    // See if we can read line #0 from the file, if not, we couldn't load the
    // file.
    const char *LineStart, *LineEnd;
    CurrentFile->getSourceLine(0, LineStart, LineEnd);
    if (LineStart == 0)
      throw "Could not load source file '" + CurrentFile->getFilename() + "'!";
    else
      std::cout << "<end of file>\n";
  }
}

void CLIDebugger::setCommand(std::string &Options) {
  std::string What = getToken(Options);

  if (What.empty())
    throw "set command expects at least two arguments.";
  if (What == "args") {
    parseProgramOptions(Options);
  } else if (What == "language") {
    std::string Lang = getToken(Options);
    if (!getToken(Options).empty())
      throw "set language expects one argument at most.";
    if (Lang == "") {
      std::cout << "The currently understood settings are:\n\n"
                << "local or auto  Automatic setting based on source file\n"
                << "c              Use the C language\n"
                << "c++            Use the C++ language\n"
                << "unknown        Use when source language is not supported\n";
    } else if (Lang == "local" || Lang == "auto") {
      CurrentLanguage = 0;
    } else if (Lang == "c") {
      CurrentLanguage = &SourceLanguage::getCFamilyInstance();
    } else if (Lang == "c++") {
      CurrentLanguage = &SourceLanguage::getCPlusPlusInstance();
    } else if (Lang == "unknown") {
      CurrentLanguage = &SourceLanguage::getUnknownLanguageInstance();
    } else {
      throw "Unknown language '" + Lang + "'.";
    }

  } else if (What == "listsize") {
    ListSize = getUnsignedIntegerOption("'set prompt' command", Options);
  } else if (What == "prompt") {
    // Include any trailing whitespace or other tokens, but not leading
    // whitespace.
    Prompt = getToken(Options);  // Strip leading whitespace
    Prompt += Options;           // Keep trailing whitespace or other stuff
  } else {
    // FIXME: Try to parse this as a source-language program expression.
    throw "Don't know how to set '" + What + "'!";
  }
}

void CLIDebugger::showCommand(std::string &Options) {
  std::string What = getToken(Options);

  if (What.empty() || !getToken(Options).empty())
    throw "show command expects one argument.";

  if (What == "args") {
    std::cout << "Argument list to give program when started is \"";
    // FIXME: This doesn't print stuff correctly if the arguments have spaces in
    // them, but currently the only way to get that is to use the --args command
    // line argument.  This should really handle escaping all hard characters as
    // needed.
    for (unsigned i = 0, e = Dbg.getNumProgramArguments(); i != e; ++i)
      std::cout << (i ? " " : "") << Dbg.getProgramArgument(i);
    std::cout << "\"\n";

  } else if (What == "language") {
    std::cout << "The current source language is '";
    if (CurrentLanguage)
      std::cout << CurrentLanguage->getSourceLanguageName();
    else
      std::cout << "auto; currently "
                << getCurrentLanguage().getSourceLanguageName();
    std::cout << "'.\n";
  } else if (What == "listsize") {
    std::cout << "Number of source lines llvm-db will list by default is "
              << ListSize << ".\n";
  } else if (What == "prompt") {
    std::cout << "llvm-db's prompt is \"" << Prompt << "\".\n";
  } else {
    throw "Unknown show command '" + What + "'.  Try 'help show'.";
  }
}

void CLIDebugger::helpCommand(std::string &Options) {
  // Print out all of the commands in the CommandTable
  std::string Command = getToken(Options);
  if (!getToken(Options).empty())
    throw "help command takes at most one argument.";

  // Getting detailed help on a particular command?
  if (!Command.empty()) {
    CLICommand *C = getCommand(Command);
    std::cout << C->getShortHelp() << ".\n" << C->getLongHelp();

    // If there are aliases for this option, print them out.
    const std::vector<std::string> &Names = C->getOptionNames();
    if (Names.size() > 1) {
      std::cout << "The '" << Command << "' command is known as: '"
                << Names[0] << "'";
      for (unsigned i = 1, e = Names.size(); i != e; ++i)
        std::cout << ", '" << Names[i] << "'";
      std::cout << "\n";
    }

  } else {
    unsigned MaxSize = 0;
    for (std::map<std::string, CLICommand*>::iterator I = CommandTable.begin(),
           E = CommandTable.end(); I != E; ++I)
      if (I->first.size() > MaxSize &&
          I->first == I->second->getPrimaryOptionName())
        MaxSize = I->first.size();

    // Loop over all of the commands, printing the short help version
    for (std::map<std::string, CLICommand*>::iterator I = CommandTable.begin(),
           E = CommandTable.end(); I != E; ++I)
      if (I->first == I->second->getPrimaryOptionName())
        std::cout << I->first << std::string(MaxSize - I->first.size(), ' ')
                  << " - " << I->second->getShortHelp() << "\n";
  }
}
