//===-- 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 is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
//===----------------------------------------------------------------------===//
-//
+//
// This file implements many builtin user commands.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/FileUtilities.h"
#include "llvm/ADT/StringExtras.h"
#include <iostream>
+#include <cstdlib>
using namespace llvm;
/// getCurrentLanguage - Return the current source language that the user is
eliminateRunInfo();
// If the program has been modified, reload it!
- std::string Program = Dbg.getProgramPath();
- if (TheProgramInfo->getProgramTimeStamp() != getFileTimestamp(Program)) {
+ 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.
TheProgramInfo = 0;
CurrentFile = 0;
- Dbg.loadProgram(Program);
+ Dbg.loadProgram(Program.toString());
TheProgramInfo = new ProgramInfo(Dbg.getProgram());
}
std::cout << " ->";
}
- std::cout << "\t" << std::string(LineStart, LineEnd) << "\n";
+ std::cout << "\t" << std::string(LineStart, LineEnd) << "\n";
return false;
}
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 << "\n";
+ if (ColNo) std::cout << ":" << ColNo;
+ std::cout << "\n";
}
if (printSourceLine(LineNo))
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())
/// 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
+static unsigned
getOptionalUnsignedIntegerOption(const char *Msg, unsigned Default,
std::string &Val, bool isOnlyOption = true) {
// Check to see if the value was specified...
// 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/bytecode file and load it. If the user does not specify
+/// 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);
unsigned CurFrame = RI.getCurrentFrameIdx();
// Check to see if we can go up the specified number of frames.
- if (CurFrame < Num)
+ 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();
// 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()) {
// 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!";
}
void CLIDebugger::infoCommand(std::string &Options) {
std::string What = getToken(Options);
- if (What.empty() || !getToken(Options).empty())
- throw "info command expects exactly one argument.";
+ if (What.empty() || !getToken(Options).empty()){
+ std::string infoStr("info");
+ helpCommand(infoStr);
+ return;
+ }
if (What == "frame") {
} else if (What == "functions") {
<< SF.getLanguage().getSourceLanguageName() << "\n";
} else if (What == "sources") {
- const std::map<const GlobalVariable*, SourceFileInfo*> &SourceFiles =
+ 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 =
std::string Name = getToken(FirstPart);
if (!getToken(FirstPart).empty())
throw "Extra junk in line specifier after '" + Name + "'.";
- SourceFunctionInfo *SFI =
+ SourceFunctionInfo *SFI =
getCurrentLanguage().lookupFunction(Name, getProgramInfo(),
TheRuntimeInfo);
if (SFI == 0)
// 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())
}
} else {
- // Parse two line specifiers...
+ // Parse two line specifiers...
const SourceFile *StartFile, *EndFile;
unsigned StartLineNo, EndLineNo;
parseLineSpec(FirstLineSpec, StartFile, StartLineNo);