Reapply r65755, but reversing "<" to ">=".
[oota-llvm.git] / tools / llvm-db / Commands.cpp
index 6df2f693a1640e0466a22065cbca666eb269bc02..ffebdd5d58f4bedfb0d2d304ed7625c9b6694d8f 100644 (file)
@@ -1,12 +1,12 @@
 //===-- 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.
 //
 //===----------------------------------------------------------------------===//
@@ -21,6 +21,7 @@
 #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
@@ -49,8 +50,12 @@ void CLIDebugger::startProgramRunning() {
   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.
@@ -59,7 +64,7 @@ void CLIDebugger::startProgramRunning() {
     TheProgramInfo = 0;
     CurrentFile = 0;
 
-    Dbg.loadProgram(Program);
+    Dbg.loadProgram(Program.toString());
     TheProgramInfo = new ProgramInfo(Dbg.getProgram());
   }
 
@@ -91,7 +96,7 @@ bool CLIDebugger::printSourceLine(unsigned LineNo) {
       std::cout << " ->";
   }
 
-  std::cout << "\t" << std::string(LineStart, LineEnd) << "\n"; 
+  std::cout << "\t" << std::string(LineStart, LineEnd) << "\n";
   return false;
 }
 
@@ -115,11 +120,12 @@ void CLIDebugger::printProgramLocation(bool PrintLocation) {
       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))
@@ -166,7 +172,7 @@ static unsigned getUnsignedIntegerOption(const char *Msg, std::string &Val,
   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())
@@ -178,7 +184,7 @@ static unsigned getUnsignedIntegerOption(const char *Msg, std::string &Val,
 /// 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...
@@ -200,13 +206,13 @@ 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
@@ -214,7 +220,7 @@ void CLIDebugger::parseProgramOptions(std::string &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);
@@ -443,11 +449,12 @@ void CLIDebugger::downCommand(std::string &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();
@@ -476,7 +483,7 @@ 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()) {
@@ -488,13 +495,13 @@ void CLIDebugger::breakCommand(std::string &Options) {
     // 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!";
 }
 
@@ -505,8 +512,11 @@ void CLIDebugger::breakCommand(std::string &Options) {
 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") {
@@ -538,7 +548,7 @@ void CLIDebugger::infoCommand(std::string &Options) {
               << 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 =
@@ -603,7 +613,7 @@ void CLIDebugger::parseLineSpec(std::string &LineSpec,
         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)
@@ -647,7 +657,7 @@ void CLIDebugger::listCommand(std::string &Options) {
 
   // 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())
@@ -685,7 +695,7 @@ void CLIDebugger::listCommand(std::string &Options) {
     }
 
   } else {
-    // Parse two line specifiers... 
+    // Parse two line specifiers...
     const SourceFile *StartFile, *EndFile;
     unsigned StartLineNo, EndLineNo;
     parseLineSpec(FirstLineSpec, StartFile, StartLineNo);