c48a919f80aac610c51012a9e23ef11ff6f30dd8
[oota-llvm.git] / tools / llvm-db / CLIDebugger.cpp
1 //===-- CLIDebugger.cpp - Command Line Interface to the Debugger ----------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 // 
10 // This file contains the main implementation of the Command Line Interface to
11 // the debugger.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "CLIDebugger.h"
16 #include "CLICommand.h"
17 #include "llvm/Debugger/SourceFile.h"
18 #include "Support/StringExtras.h"
19 #include <iostream>
20 using namespace llvm;
21
22 /// CLIDebugger constructor - This initializes the debugger to its default
23 /// state, and initializes the command table.
24 ///
25 CLIDebugger::CLIDebugger()
26   : TheProgramInfo(0), TheRuntimeInfo(0), Prompt("(llvm-db) "), ListSize(10) {
27   // Initialize instance variables
28   CurrentFile = 0;
29   LineListedStart = 1;
30   LineListedEnd = 1;
31   LastCurrentFrame = 0;
32   CurrentLanguage = 0;
33
34   CLICommand *C;
35   //===--------------------------------------------------------------------===//
36   // Program startup and shutdown options
37   //
38   addCommand("file", new BuiltinCLICommand(
39     "Use specified file as the program to be debugged",
40     "The debugger looks in the current directory and the program $PATH for the"
41     " specified LLVM program.  It then unloads the currently loaded program and"
42     " loads the specified program.\n",
43     &CLIDebugger::fileCommand));
44
45   addCommand("create", new BuiltinCLICommand(
46     "Start the program, halting its execution in main",
47     "This command creates an instance of the current program, but stops"
48     "\nexecution immediately.\n",
49     &CLIDebugger::createCommand));
50
51   addCommand("kill", new BuiltinCLICommand(
52     "Kills the execution of the current program being debugged", "",
53     &CLIDebugger::killCommand));
54
55   addCommand("quit", new BuiltinCLICommand(
56     "Exit the debugger", "",
57     &CLIDebugger::quitCommand));
58
59   //===--------------------------------------------------------------------===//
60   // Program execution commands
61   //
62   addCommand("run", C = new BuiltinCLICommand(
63     "Start the program running from the beginning", "",
64     &CLIDebugger::runCommand));
65   addCommand("r", C);
66
67   addCommand("cont", C = new BuiltinCLICommand(
68     "Continue program being debugged until the next stop point", "",
69     &CLIDebugger::contCommand));
70   addCommand("c", C); addCommand("fg", C);
71
72   addCommand("step", C = new BuiltinCLICommand(
73     "Step program until it reaches a new source line", "",
74     &CLIDebugger::stepCommand));
75   addCommand("s", C);
76
77   addCommand("next", C = new BuiltinCLICommand(
78     "Step program until it reaches a new source line, stepping over calls", "",
79     &CLIDebugger::nextCommand));
80   addCommand("n", C); 
81
82   addCommand("finish", new BuiltinCLICommand(
83     "Execute until the selected stack frame returns",
84    "Upon return, the value returned is printed and put in the value history.\n",
85     &CLIDebugger::finishCommand));
86
87   //===--------------------------------------------------------------------===//
88   // Stack frame commands
89   //
90   addCommand("backtrace", C = new BuiltinCLICommand(
91    "Print backtrace of all stack frames, or innermost COUNT frames",
92    "FIXME: describe.  Takes 'n', '-n' or 'full'\n",
93     &CLIDebugger::backtraceCommand));
94   addCommand("bt", C); 
95  
96   addCommand("up", new BuiltinCLICommand(
97     "Select and print stack frame that called this one",
98     "An argument says how many frames up to go.\n",
99     &CLIDebugger::upCommand));
100
101   addCommand("down", new BuiltinCLICommand(
102     "Select and print stack frame called by this one",
103     "An argument says how many frames down go.\n",
104     &CLIDebugger::downCommand));
105
106   addCommand("frame", C = new BuiltinCLICommand(
107     "Select and print a stack frame",
108  "With no argument, print the selected stack frame.  (See also 'info frame').\n"
109  "An argument specifies the frame to select.\n",
110     &CLIDebugger::frameCommand));
111   addCommand("f", C); 
112
113   //===--------------------------------------------------------------------===//
114   // Breakpoint related commands
115   //
116   addCommand("break", C = new BuiltinCLICommand(
117    "Set breakpoint at specified line or function",
118    "FIXME: describe.\n",
119     &CLIDebugger::breakCommand));
120   addCommand("b", C); 
121
122
123   //===--------------------------------------------------------------------===//
124   // Miscellaneous commands
125   //
126   addCommand("info", new BuiltinCLICommand(
127     "Generic command for showing things about the program being debugged",
128     "FIXME: document\n",
129     &CLIDebugger::infoCommand));
130
131   addCommand("list", C = new BuiltinCLICommand(
132     "List specified function or line",
133     "FIXME: document\n",
134     &CLIDebugger::listCommand));
135   addCommand("l", C);
136
137   addCommand("set", new BuiltinCLICommand(
138     "Change program or debugger variable",
139     "FIXME: document\n",
140     &CLIDebugger::setCommand));
141
142   addCommand("show", new BuiltinCLICommand(
143     "Generic command for showing things about the debugger",
144     "FIXME: document\n",
145     &CLIDebugger::showCommand));
146
147   addCommand("help", C = new BuiltinCLICommand(
148     "Prints information about available commands", "",
149     &CLIDebugger::helpCommand));
150   addCommand("h", C);
151 }
152
153
154 /// addCommand - Add a command to the CommandTable, potentially displacing a
155 /// preexisting command.
156 void CLIDebugger::addCommand(const std::string &Option, CLICommand *Cmd) {
157   assert(Cmd && "Cannot set a null command!");
158   CLICommand *&CS = CommandTable[Option];
159   if (CS == Cmd) return; // noop
160
161   // If we already have a command, decrement the command's reference count.
162   if (CS) {
163     CS->removeOptionName(Option);
164     CS->dropRef();
165   }
166   CS = Cmd;
167
168   // Remember that we are using this command.
169   Cmd->addRef();
170   Cmd->addOptionName(Option);
171 }
172
173 static bool isValidPrefix(const std::string &Prefix, const std::string &Option){
174   return Prefix.size() <= Option.size() &&
175          Prefix == std::string(Option.begin(), Option.begin()+Prefix.size());
176 }
177
178 /// getCommand - This looks up the specified command using a fuzzy match.
179 /// If the string exactly matches a command or is an unambiguous prefix of a
180 /// command, it returns the command.  Otherwise it throws an exception
181 /// indicating the possible ambiguous choices.
182 CLICommand *CLIDebugger::getCommand(const std::string &Command) {
183
184   // Look up the command in the table.
185   std::map<std::string, CLICommand*>::iterator CI =
186     CommandTable.lower_bound(Command);
187       
188   if (Command == "") {
189     throw "Null command should not get here!";
190   } else if (CI == CommandTable.end() ||
191              !isValidPrefix(Command, CI->first)) {
192     // If this command has no relation to anything in the command table,
193     // print the error message.
194     throw "Unknown command: '" + Command +
195           "'.  Use 'help' for list of commands.";
196   } else if (CI->first == Command) {
197     // We have an exact match on the command
198     return CI->second;
199   } else {
200     // Otherwise, we have a prefix match.  Check to see if this is
201     // unambiguous, and if so, run it.
202     std::map<std::string, CLICommand*>::iterator CI2 = CI;
203
204     // If the next command is a valid completion of this one, we are
205     // ambiguous.
206     if (++CI2 != CommandTable.end() && isValidPrefix(Command, CI2->first)) {
207       std::string ErrorMsg = 
208         "Ambiguous command '" + Command + "'.  Options: " + CI->first;
209       for (++CI; CI != CommandTable.end() &&
210              isValidPrefix(Command, CI->first); ++CI)
211         ErrorMsg += ", " + CI->first;
212       throw ErrorMsg;
213     } else {
214       // It's an unambiguous prefix of a command, use it.
215       return CI->second;
216     }
217   }
218 }
219
220
221 /// run - Start the debugger, returning when the user exits the debugger.  This
222 /// starts the main event loop of the CLI debugger.
223 ///
224 int CLIDebugger::run() {
225   std::string Command;
226   std::cout << Prompt;
227
228   // Keep track of the last command issued, so that we can reissue it if the
229   // user hits enter as the command.
230   CLICommand *LastCommand = 0;
231   std::string LastArgs;
232
233   // Continue reading commands until the end of file.
234   while (getline(std::cin, Command)) {
235     std::string Arguments = Command;
236
237     // Split off the command from the arguments to the command.
238     Command = getToken(Arguments, " \t\n\v\f\r\\/;.*&");
239
240     try {
241       CLICommand *CurCommand;
242       
243       if (Command == "") {
244         CurCommand = LastCommand;
245         Arguments = LastArgs;
246       } else {
247         CurCommand = getCommand(Command);
248       }
249
250       // Save the command we are running in case the user wants us to repeat it
251       // next time.
252       LastCommand = CurCommand;
253       LastArgs = Arguments;
254
255       // Finally, execute the command.
256       if (CurCommand)
257         CurCommand->runCommand(*this, Arguments);      
258
259     } catch (int RetVal) {
260       // The quit command exits the command loop by throwing an integer return
261       // code.
262       return RetVal;
263     } catch (const std::string &Error) {
264       std::cout << "Error: " << Error << "\n";
265     } catch (const char *Error) {
266       std::cout << "Error: " << Error << "\n";
267     } catch (const NonErrorException &E) {
268       std::cout << E.getMessage() << "\n";
269     } catch (...) {
270       std::cout << "ERROR: Debugger caught unexpected exception!\n";
271       // Attempt to continue.
272     }
273     
274     // Write the prompt to get the next bit of user input
275     std::cout << Prompt;
276   }
277
278   return 0;
279 }
280
281
282 /// askYesNo - Ask the user a question, and demand a yes/no response.  If
283 /// the user says yes, return true.
284 ///
285 bool CLIDebugger::askYesNo(const std::string &Message) const {
286   std::string Answer;
287   std::cout << Message << " (y or n) " << std::flush;
288   while (getline(std::cin, Answer)) {
289     std::string Val = getToken(Answer);
290     if (getToken(Answer).empty()) {
291       if (Val == "yes" || Val == "y" || Val == "YES" || Val == "Y" ||
292           Val == "Yes")
293         return true;
294       if (Val == "no" || Val == "n" || Val == "NO" || Val == "N" ||
295           Val == "No")
296         return false;
297     }
298
299     std::cout << "Please answer y or n.\n" << Message << " (y or n) "
300               << std::flush;
301   }
302   
303   // Ran out of input?
304   return false;
305 }