//===-- 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 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 "Support/StringExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include <iostream>
using namespace llvm;
&CLIDebugger::fileCommand));
addCommand("create", new BuiltinCLICommand(
- "Start the current program, stopping execution in main",
+ "Start the program, halting its execution in main",
"This command creates an instance of the current program, but stops"
- " execution immediately.",
+ "\nexecution immediately.\n",
&CLIDebugger::createCommand));
addCommand("kill", new BuiltinCLICommand(
addCommand("next", C = new BuiltinCLICommand(
"Step program until it reaches a new source line, stepping over calls", "",
&CLIDebugger::nextCommand));
- addCommand("n", C);
+ addCommand("n", C);
addCommand("finish", new BuiltinCLICommand(
"Execute until the selected stack frame returns",
"Print backtrace of all stack frames, or innermost COUNT frames",
"FIXME: describe. Takes 'n', '-n' or 'full'\n",
&CLIDebugger::backtraceCommand));
- addCommand("bt", C);
-
+ 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",
"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);
+ addCommand("f", C);
//===--------------------------------------------------------------------===//
// Breakpoint related commands
"Set breakpoint at specified line or function",
"FIXME: describe.\n",
&CLIDebugger::breakCommand));
- addCommand("b", C);
+ addCommand("b", C);
//===--------------------------------------------------------------------===//
//
addCommand("info", new BuiltinCLICommand(
"Generic command for showing things about the program being debugged",
- "FIXME: document\n",
+ "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(
// Look up the command in the table.
std::map<std::string, CLICommand*>::iterator CI =
CommandTable.lower_bound(Command);
-
+
if (Command == "") {
- throw "Null command not implemented yet.";
+ 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,
// 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 =
+ std::string ErrorMsg =
"Ambiguous command '" + Command + "'. Options: " + CI->first;
for (++CI; CI != CommandTable.end() &&
isValidPrefix(Command, CI->first); ++CI)
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;
Command = getToken(Arguments, " \t\n\v\f\r\\/;.*&");
try {
- // Look up the command and execute it.
- getCommand(Command)->runCommand(*this, Arguments);
+ 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
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;
}
std::cout << "Please answer y or n.\n" << Message << " (y or n) "
<< std::flush;
}
-
+
// Ran out of input?
return false;
}