Fix a bug that caused stuff like this:
[oota-llvm.git] / tools / llvm-db / Commands.cpp
1 //===-- Commands.cpp - Implement various commands for the CLI -------------===//
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 implements many builtin user commands.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CLIDebugger.h"
15 #include "CLICommand.h"
16 #include "llvm/Debugger/ProgramInfo.h"
17 #include "llvm/Debugger/RuntimeInfo.h"
18 #include "llvm/Debugger/SourceLanguage.h"
19 #include "llvm/Debugger/SourceFile.h"
20 #include "llvm/Debugger/InferiorProcess.h"
21 #include "llvm/Support/FileUtilities.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include <iostream>
24 using namespace llvm;
25
26 /// getCurrentLanguage - Return the current source language that the user is
27 /// playing around with.  This is aquired from the current stack frame of a
28 /// running program if one exists, but this value can be explicitly set by the
29 /// user as well.
30 const SourceLanguage &CLIDebugger::getCurrentLanguage() const {
31   // If the user explicitly switched languages with 'set language', use what
32   // they asked for.
33   if (CurrentLanguage) {
34     return *CurrentLanguage;
35   } else if (Dbg.isProgramRunning()) {
36     // Otherwise, if the program is running, infer the current language from it.
37     const GlobalVariable *FuncDesc =
38       getRuntimeInfo().getCurrentFrame().getFunctionDesc();
39     return getProgramInfo().getFunction(FuncDesc).getSourceFile().getLanguage();
40   } else {
41     // Otherwise, default to C like GDB apparently does.
42     return SourceLanguage::getCFamilyInstance();
43   }
44 }
45
46 /// startProgramRunning - If the program has been updated, reload it, then
47 /// start executing the program.
48 void CLIDebugger::startProgramRunning() {
49   eliminateRunInfo();
50
51   // If the program has been modified, reload it!
52   std::string Program = Dbg.getProgramPath();
53   if (TheProgramInfo->getProgramTimeStamp() != getFileTimestamp(Program)) {
54     std::cout << "'" << Program << "' has changed; re-reading program.\n";
55
56     // Unload an existing program.  This kills the program if necessary.
57     Dbg.unloadProgram();
58     delete TheProgramInfo;
59     TheProgramInfo = 0;
60     CurrentFile = 0;
61
62     Dbg.loadProgram(Program);
63     TheProgramInfo = new ProgramInfo(Dbg.getProgram());
64   }
65
66   std::cout << "Starting program: " << Dbg.getProgramPath() << "\n";
67   Dbg.createProgram();
68
69   // There was no current frame.
70   LastCurrentFrame = 0;
71 }
72
73 /// printSourceLine - Print the specified line of the current source file.
74 /// If the specified line is invalid (the source file could not be loaded or
75 /// the line number is out of range), don't print anything, but return true.
76 bool CLIDebugger::printSourceLine(unsigned LineNo) {
77   assert(CurrentFile && "There is no current source file to print!");
78   const char *LineStart, *LineEnd;
79   CurrentFile->getSourceLine(LineNo-1, LineStart, LineEnd);
80   if (LineStart == 0) return true;
81   std::cout << LineNo;
82
83   // If this is the line the program is currently stopped at, print a marker.
84   if (Dbg.isProgramRunning()) {
85     unsigned CurLineNo, CurColNo;
86     const SourceFileInfo *CurSFI;
87     getRuntimeInfo().getCurrentFrame().getSourceLocation(CurLineNo, CurColNo,
88                                                          CurSFI);
89
90     if (CurLineNo == LineNo && CurrentFile == &CurSFI->getSourceText())
91       std::cout << " ->";
92   }
93
94   std::cout << "\t" << std::string(LineStart, LineEnd) << "\n"; 
95   return false;
96 }
97
98 /// printProgramLocation - Print a line of the place where the current stack
99 /// frame has stopped and the source line it is on.
100 ///
101 void CLIDebugger::printProgramLocation(bool PrintLocation) {
102   assert(Dbg.isProgramLoaded() && Dbg.isProgramRunning() &&
103          "Error program is not loaded and running!");
104
105   // Figure out where the program stopped...
106   StackFrame &SF = getRuntimeInfo().getCurrentFrame();
107   unsigned LineNo, ColNo;
108   const SourceFileInfo *FileDesc;
109   SF.getSourceLocation(LineNo, ColNo, FileDesc);
110
111   // If requested, print out some program information about WHERE we are.
112   if (PrintLocation) {
113     // FIXME: print the current function arguments
114     if (const GlobalVariable *FuncDesc = SF.getFunctionDesc())
115       std::cout << getProgramInfo().getFunction(FuncDesc).getSymbolicName();
116     else
117       std::cout << "<unknown function>";
118     
119     CurrentFile = &FileDesc->getSourceText();
120     
121     std::cout << " at " << CurrentFile->getFilename() << ":" << LineNo;
122     if (ColNo) std::cout << ":" << ColNo;
123     std::cout << "\n";
124   }
125
126   if (printSourceLine(LineNo))
127     std::cout << "<could not load source file>\n";
128   else {
129     LineListedStart = LineNo-ListSize/2+1;
130     if ((int)LineListedStart < 1) LineListedStart = 1;
131     LineListedEnd = LineListedStart+1;
132   }
133 }
134
135 /// eliminateRunInfo - We are about to run the program.  Forget any state
136 /// about how the program used to be stopped.
137 void CLIDebugger::eliminateRunInfo() {
138   delete TheRuntimeInfo;
139   TheRuntimeInfo = 0;
140 }
141
142 /// programStoppedSuccessfully - This method updates internal data
143 /// structures to reflect the fact that the program just executed a while,
144 /// and has successfully stopped.
145 void CLIDebugger::programStoppedSuccessfully() {
146   assert(TheRuntimeInfo==0 && "Someone forgot to release the old RuntimeInfo!");
147
148   TheRuntimeInfo = new RuntimeInfo(TheProgramInfo, Dbg.getRunningProcess());
149
150   // FIXME: if there are any breakpoints at the current location, print them as
151   // well.
152
153   // Since the program as successfully stopped, print its location.
154   void *CurrentFrame = getRuntimeInfo().getCurrentFrame().getFrameID();
155   printProgramLocation(CurrentFrame != LastCurrentFrame);
156   LastCurrentFrame = CurrentFrame;
157 }
158
159
160
161 /// getUnsignedIntegerOption - Get an unsigned integer number from the Val
162 /// string.  Check to make sure that the string contains an unsigned integer
163 /// token, and if not, throw an exception.  If isOnlyOption is set, also throw
164 /// an exception if there is extra junk at the end of the string.
165 static unsigned getUnsignedIntegerOption(const char *Msg, std::string &Val,
166                                          bool isOnlyOption = true) {
167   std::string Tok = getToken(Val);
168   if (Tok.empty() || (isOnlyOption && !getToken(Val).empty()))
169     throw std::string(Msg) + " expects an unsigned integer argument.";
170   
171   char *EndPtr;
172   unsigned Result = strtoul(Tok.c_str(), &EndPtr, 0);
173   if (EndPtr != Tok.c_str()+Tok.size())
174     throw std::string(Msg) + " expects an unsigned integer argument.";
175
176   return Result;
177 }
178
179 /// getOptionalUnsignedIntegerOption - This method is just like
180 /// getUnsignedIntegerOption, but if the argument value is not specified, a
181 /// default is returned instead of causing an error.
182 static unsigned 
183 getOptionalUnsignedIntegerOption(const char *Msg, unsigned Default,
184                                  std::string &Val, bool isOnlyOption = true) {
185   // Check to see if the value was specified...
186   std::string TokVal = getToken(Val);
187   if (TokVal.empty()) return Default;
188
189   // If it was specified, add it back to the value we are parsing...
190   Val = TokVal+Val;
191
192   // And parse normally.
193   return getUnsignedIntegerOption(Msg, Val, isOnlyOption);
194 }
195
196
197 /// parseProgramOptions - This method parses the Options string and loads it
198 /// as options to be passed to the program.  This is used by the run command
199 /// and by 'set args'.
200 void CLIDebugger::parseProgramOptions(std::string &Options) {
201   // FIXME: tokenizing by whitespace is clearly incorrect.  Instead we should
202   // honor quotes and other things that a shell would.  Also in the future we
203   // should support redirection of standard IO.
204  
205   std::vector<std::string> Arguments;
206   for (std::string A = getToken(Options); !A.empty(); A = getToken(Options))
207     Arguments.push_back(A);
208   Dbg.setProgramArguments(Arguments.begin(), Arguments.end());
209 }
210                                                 
211
212 //===----------------------------------------------------------------------===//
213 //                   Program startup and shutdown options
214 //===----------------------------------------------------------------------===//
215
216
217 /// file command - If the user specifies an option, search the PATH for the
218 /// specified program/bytecode file and load it.  If the user does not specify
219 /// an option, unload the current program.
220 void CLIDebugger::fileCommand(std::string &Options) {
221   std::string Prog = getToken(Options);
222   if (!getToken(Options).empty())
223     throw "file command takes at most one argument.";
224
225   // Check to make sure the user knows what they are doing
226   if (Dbg.isProgramRunning() &&
227       !askYesNo("A program is already loaded.  Kill it?"))
228     return;
229
230   // Unload an existing program.  This kills the program if necessary.
231   eliminateRunInfo();
232   delete TheProgramInfo;
233   TheProgramInfo = 0;
234   Dbg.unloadProgram();
235   CurrentFile = 0;
236
237   // If requested, start the new program.
238   if (Prog.empty()) {
239     std::cout << "Unloaded program.\n";
240   } else {
241     std::cout << "Loading program... " << std::flush;
242     Dbg.loadProgram(Prog);
243     assert(Dbg.isProgramLoaded() &&
244            "loadProgram succeeded, but not program loaded!");
245     TheProgramInfo = new ProgramInfo(Dbg.getProgram());
246     std::cout << "successfully loaded '" << Dbg.getProgramPath() << "'!\n";
247   }
248 }
249
250
251 void CLIDebugger::createCommand(std::string &Options) {
252   if (!getToken(Options).empty())
253     throw "create command does not take any arguments.";
254   if (!Dbg.isProgramLoaded()) throw "No program loaded.";
255   if (Dbg.isProgramRunning() &&
256       !askYesNo("The program is already running.  Restart from the beginning?"))
257     return;
258
259   // Start the program running.
260   startProgramRunning();
261
262   // The program stopped!
263   programStoppedSuccessfully();
264 }
265
266 void CLIDebugger::killCommand(std::string &Options) {
267   if (!getToken(Options).empty())
268     throw "kill command does not take any arguments.";
269   if (!Dbg.isProgramRunning())
270     throw "No program is currently being run.";
271
272   if (askYesNo("Kill the program being debugged?"))
273     Dbg.killProgram();
274   eliminateRunInfo();
275 }
276
277 void CLIDebugger::quitCommand(std::string &Options) {
278   if (!getToken(Options).empty())
279     throw "quit command does not take any arguments.";
280
281   if (Dbg.isProgramRunning() &&
282       !askYesNo("The program is running.  Exit anyway?"))
283     return;
284
285   // Throw exception to get out of the user-input loop.
286   throw 0;
287 }
288
289
290 //===----------------------------------------------------------------------===//
291 //                        Program execution commands
292 //===----------------------------------------------------------------------===//
293
294 void CLIDebugger::runCommand(std::string &Options) {
295   if (!Dbg.isProgramLoaded()) throw "No program loaded.";
296   if (Dbg.isProgramRunning() &&
297       !askYesNo("The program is already running.  Restart from the beginning?"))
298     return;
299
300   // Parse all of the options to the run command, which specify program
301   // arguments to run with.
302   parseProgramOptions(Options);
303
304   eliminateRunInfo();
305
306   // Start the program running.
307   startProgramRunning();
308
309   // Start the program running...
310   Options = "";
311   contCommand(Options);
312 }
313
314 void CLIDebugger::contCommand(std::string &Options) {
315   if (!getToken(Options).empty()) throw "cont argument not supported yet.";
316   if (!Dbg.isProgramRunning()) throw "Program is not running.";
317
318   eliminateRunInfo();
319
320   Dbg.contProgram();
321
322   // The program stopped!
323   programStoppedSuccessfully();
324 }
325
326 void CLIDebugger::stepCommand(std::string &Options) {
327   if (!Dbg.isProgramRunning()) throw "Program is not running.";
328
329   // Figure out how many times to step.
330   unsigned Amount =
331     getOptionalUnsignedIntegerOption("'step' command", 1, Options);
332
333   eliminateRunInfo();
334
335   // Step the specified number of times.
336   for (; Amount; --Amount)
337     Dbg.stepProgram();
338
339   // The program stopped!
340   programStoppedSuccessfully();
341 }
342
343 void CLIDebugger::nextCommand(std::string &Options) {
344   if (!Dbg.isProgramRunning()) throw "Program is not running.";
345   unsigned Amount =
346     getOptionalUnsignedIntegerOption("'next' command", 1, Options);
347
348   eliminateRunInfo();
349
350   for (; Amount; --Amount)
351     Dbg.nextProgram();
352
353   // The program stopped!
354   programStoppedSuccessfully();
355 }
356
357 void CLIDebugger::finishCommand(std::string &Options) {
358   if (!getToken(Options).empty())
359     throw "finish command does not take any arguments.";
360   if (!Dbg.isProgramRunning()) throw "Program is not running.";
361
362   // Figure out where we are exactly.  If the user requests that we return from
363   // a frame that is not the top frame, make sure we get it.
364   void *CurrentFrame = getRuntimeInfo().getCurrentFrame().getFrameID();
365
366   eliminateRunInfo();
367
368   Dbg.finishProgram(CurrentFrame);
369
370   // The program stopped!
371   programStoppedSuccessfully();
372 }
373
374 //===----------------------------------------------------------------------===//
375 //                           Stack frame commands
376 //===----------------------------------------------------------------------===//
377
378 void CLIDebugger::backtraceCommand(std::string &Options) {
379   // Accepts "full", n, -n
380   if (!getToken(Options).empty())
381     throw "FIXME: bt command argument not implemented yet!";
382
383   RuntimeInfo &RI = getRuntimeInfo();
384   ProgramInfo &PI = getProgramInfo();
385
386   try {
387     for (unsigned i = 0; ; ++i) {
388       StackFrame &SF = RI.getStackFrame(i);
389       std::cout << "#" << i;
390       if (i == RI.getCurrentFrameIdx())
391         std::cout << " ->";
392       std::cout << "\t" << SF.getFrameID() << " in ";
393       if (const GlobalVariable *G = SF.getFunctionDesc())
394         std::cout << PI.getFunction(G).getSymbolicName();
395
396       unsigned LineNo, ColNo;
397       const SourceFileInfo *SFI;
398       SF.getSourceLocation(LineNo, ColNo, SFI);
399       if (!SFI->getBaseName().empty()) {
400         std::cout << " at " << SFI->getBaseName();
401         if (LineNo) {
402           std::cout << ":" << LineNo;
403           if (ColNo)
404             std::cout << ":" << ColNo;
405         }
406       }
407
408       // FIXME: when we support shared libraries, we should print ' from foo.so'
409       // if the stack frame is from a different object than the current one.
410
411       std::cout << "\n";
412     }
413   } catch (...) {
414     // Stop automatically when we run off the bottom of the stack.
415   }
416 }
417
418 void CLIDebugger::upCommand(std::string &Options) {
419   unsigned Num =
420     getOptionalUnsignedIntegerOption("'up' command", 1, Options);
421
422   RuntimeInfo &RI = getRuntimeInfo();
423   unsigned CurFrame = RI.getCurrentFrameIdx();
424
425   // Check to see if we go can up the specified number of frames.
426   try {
427     RI.getStackFrame(CurFrame+Num);
428   } catch (...) {
429     if (Num == 1)
430       throw "Initial frame selected; you cannot go up.";
431     else
432       throw "Cannot go up " + utostr(Num) + " frames!";
433   }
434
435   RI.setCurrentFrameIdx(CurFrame+Num);
436   printProgramLocation();
437 }
438
439 void CLIDebugger::downCommand(std::string &Options) {
440   unsigned Num =
441     getOptionalUnsignedIntegerOption("'down' command", 1, Options);
442
443   RuntimeInfo &RI = getRuntimeInfo();
444   unsigned CurFrame = RI.getCurrentFrameIdx();
445
446   // Check to see if we can go up the specified number of frames.
447   if (CurFrame < Num)
448     if (Num == 1)
449       throw "Bottom (i.e., innermost) frame selected; you cannot go down.";
450     else
451       throw "Cannot go down " + utostr(Num) + " frames!";
452
453   RI.setCurrentFrameIdx(CurFrame-Num);
454   printProgramLocation();
455 }
456
457 void CLIDebugger::frameCommand(std::string &Options) {
458   RuntimeInfo &RI = getRuntimeInfo();
459   unsigned CurFrame = RI.getCurrentFrameIdx();
460
461   unsigned Num =
462     getOptionalUnsignedIntegerOption("'frame' command", CurFrame, Options);
463
464   // Check to see if we go to the specified frame.
465   RI.getStackFrame(Num);
466
467   RI.setCurrentFrameIdx(Num);
468   printProgramLocation();
469 }
470
471
472 //===----------------------------------------------------------------------===//
473 //                        Breakpoint related commands
474 //===----------------------------------------------------------------------===//
475
476 void CLIDebugger::breakCommand(std::string &Options) {
477   // Figure out where the user wants a breakpoint.
478   const SourceFile *File;
479   unsigned LineNo;
480   
481   // Check to see if the user specified a line specifier.
482   std::string Option = getToken(Options);  // strip whitespace
483   if (!Option.empty()) {
484     Options = Option + Options;  // reconstruct string
485
486     // Parse the line specifier.
487     parseLineSpec(Options, File, LineNo);
488   } else {
489     // Build a line specifier for the current stack frame.
490     throw "FIXME: breaking at the current location is not implemented yet!";
491   }
492   
493   if (!File) File = CurrentFile;
494   if (File == 0)
495     throw "Unknown file to place breakpoint!";
496
497   std::cerr << "Break: " << File->getFilename() << ":" << LineNo << "\n";
498   
499   throw "breakpoints not implemented yet!";
500 }
501
502 //===----------------------------------------------------------------------===//
503 //                          Miscellaneous commands
504 //===----------------------------------------------------------------------===//
505
506 void CLIDebugger::infoCommand(std::string &Options) {
507   std::string What = getToken(Options);
508
509   if (What.empty() || !getToken(Options).empty()){
510     std::string infoStr("info");
511     helpCommand(infoStr);
512     return;
513   }
514
515   if (What == "frame") {
516   } else if (What == "functions") {
517     const std::map<const GlobalVariable*, SourceFunctionInfo*> &Functions
518       = getProgramInfo().getSourceFunctions();
519     std::cout << "All defined functions:\n";
520     // FIXME: GDB groups these by source file.  We could do that I guess.
521     for (std::map<const GlobalVariable*, SourceFunctionInfo*>::const_iterator
522            I = Functions.begin(), E = Functions.end(); I != E; ++I) {
523       std::cout << I->second->getSymbolicName() << "\n";
524     }
525
526   } else if (What == "source") {
527     if (CurrentFile == 0)
528       throw "No current source file.";
529
530     // Get the SourceFile information for the current file.
531     const SourceFileInfo &SF =
532       getProgramInfo().getSourceFile(CurrentFile->getDescriptor());
533
534     std::cout << "Current source file is: " << SF.getBaseName() << "\n"
535               << "Compilation directory is: " << SF.getDirectory() << "\n";
536     if (unsigned NL = CurrentFile->getNumLines())
537       std::cout << "Located in: " << CurrentFile->getFilename() << "\n"
538                 << "Contains " << NL << " lines\n";
539     else
540       std::cout << "Could not find source file.\n";
541     std::cout << "Source language is "
542               << SF.getLanguage().getSourceLanguageName() << "\n";
543
544   } else if (What == "sources") {
545     const std::map<const GlobalVariable*, SourceFileInfo*> &SourceFiles = 
546       getProgramInfo().getSourceFiles();
547     std::cout << "Source files for the program:\n";
548     for (std::map<const GlobalVariable*, SourceFileInfo*>::const_iterator I =
549            SourceFiles.begin(), E = SourceFiles.end(); I != E;) {
550       std::cout << I->second->getDirectory() << "/"
551                 << I->second->getBaseName();
552       ++I;
553       if (I != E) std::cout << ", ";
554     }
555     std::cout << "\n";
556   } else if (What == "target") {
557     std::cout << Dbg.getRunningProcess().getStatus();
558   } else {
559     // See if this is something handled by the current language.
560     if (getCurrentLanguage().printInfo(What))
561       return;
562
563     throw "Unknown info command '" + What + "'.  Try 'help info'.";
564   }
565 }
566
567 /// parseLineSpec - Parses a line specifier, for use by the 'list' command.
568 /// If SourceFile is returned as a void pointer, then it was not specified.
569 /// If the line specifier is invalid, an exception is thrown.
570 void CLIDebugger::parseLineSpec(std::string &LineSpec,
571                                 const SourceFile *&SourceFile,
572                                 unsigned &LineNo) {
573   SourceFile = 0;
574   LineNo = 0;
575
576   // First, check to see if we have a : separator.
577   std::string FirstPart = getToken(LineSpec, ":");
578   std::string SecondPart = getToken(LineSpec, ":");
579   if (!getToken(LineSpec).empty()) throw "Malformed line specification!";
580
581   // If there is no second part, we must have either "function", "number",
582   // "+offset", or "-offset".
583   if (SecondPart.empty()) {
584     if (FirstPart.empty()) throw "Malformed line specification!";
585     if (FirstPart[0] == '+') {
586       FirstPart.erase(FirstPart.begin(), FirstPart.begin()+1);
587       // For +n, return LineListedEnd+n
588       LineNo = LineListedEnd +
589                getUnsignedIntegerOption("Line specifier '+'", FirstPart);
590
591     } else if (FirstPart[0] == '-') {
592       FirstPart.erase(FirstPart.begin(), FirstPart.begin()+1);
593       // For -n, return LineListedEnd-n
594       LineNo = LineListedEnd -
595                getUnsignedIntegerOption("Line specifier '-'", FirstPart);
596       if ((int)LineNo < 1) LineNo = 1;
597     } else if (FirstPart[0] == '*') {
598       throw "Address expressions not supported as source locations!";
599     } else {
600       // Ok, check to see if this is just a line number.
601       std::string Saved = FirstPart;
602       try {
603         LineNo = getUnsignedIntegerOption("", Saved);
604       } catch (...) {
605         // Ok, it's not a valid line number.  It must be a source-language
606         // entity name.
607         std::string Name = getToken(FirstPart);
608         if (!getToken(FirstPart).empty())
609           throw "Extra junk in line specifier after '" + Name + "'.";
610         SourceFunctionInfo *SFI = 
611           getCurrentLanguage().lookupFunction(Name, getProgramInfo(),
612                                               TheRuntimeInfo);
613         if (SFI == 0)
614           throw "Unknown identifier '" + Name + "'.";
615
616         unsigned L, C;
617         SFI->getSourceLocation(L, C);
618         if (L == 0) throw "Could not locate '" + Name + "'!";
619         LineNo = L;
620         SourceFile = &SFI->getSourceFile().getSourceText();
621         return;
622       }
623     }
624
625   } else {
626     // Ok, this must be a filename qualified line number or function name.
627     // First, figure out the source filename.
628     std::string SourceFilename = getToken(FirstPart);
629     if (!getToken(FirstPart).empty())
630       throw "Invalid filename qualified source location!";
631
632     // Next, check to see if this is just a line number.
633     std::string Saved = SecondPart;
634     try {
635       LineNo = getUnsignedIntegerOption("", Saved);
636     } catch (...) {
637       // Ok, it's not a valid line number.  It must be a function name.
638       throw "FIXME: Filename qualified function names are not support "
639             "as line specifiers yet!";
640     }
641
642     // Ok, we got the line number.  Now check out the source file name to make
643     // sure it's all good.  If it is, return it.  If not, throw exception.
644     SourceFile =&getProgramInfo().getSourceFile(SourceFilename).getSourceText();
645   }
646 }
647
648 void CLIDebugger::listCommand(std::string &Options) {
649   if (!Dbg.isProgramLoaded())
650     throw "No program is loaded.  Use the 'file' command.";
651
652   // Handle "list foo," correctly, by returning " " as the second token
653   Options += " ";
654   
655   std::string FirstLineSpec = getToken(Options, ",");
656   std::string SecondLineSpec = getToken(Options, ",");
657   if (!getToken(Options, ",").empty())
658     throw "list command only expects two source location specifiers!";
659
660   // StartLine, EndLine - The starting and ending line numbers to print.
661   unsigned StartLine = 0, EndLine = 0;
662
663   if (SecondLineSpec.empty()) {    // No second line specifier provided?
664     // Handle special forms like "", "+", "-", etc.
665     std::string TmpSpec = FirstLineSpec;
666     std::string Tok = getToken(TmpSpec);
667     if (getToken(TmpSpec).empty() && (Tok == "" || Tok == "+" || Tok == "-")) {
668       if (Tok == "+" || Tok == "") {
669         StartLine = LineListedEnd;
670         EndLine = StartLine + ListSize;
671       } else {
672         assert(Tok == "-");
673         StartLine = LineListedStart-ListSize;
674         EndLine = LineListedStart;
675         if ((int)StartLine <= 0) StartLine = 1;
676       }
677     } else {
678       // Must be a normal line specifier.
679       const SourceFile *File;
680       unsigned LineNo;
681       parseLineSpec(FirstLineSpec, File, LineNo);
682
683       // If the user only specified one file specifier, we should display
684       // ListSize lines centered at the specified line.
685       if (File != 0) CurrentFile = File;
686       StartLine = LineNo - (ListSize+1)/2;
687       if ((int)StartLine <= 0) StartLine = 1;
688       EndLine = StartLine + ListSize;
689     }
690
691   } else {
692     // Parse two line specifiers... 
693     const SourceFile *StartFile, *EndFile;
694     unsigned StartLineNo, EndLineNo;
695     parseLineSpec(FirstLineSpec, StartFile, StartLineNo);
696     unsigned SavedLLE = LineListedEnd;
697     LineListedEnd = StartLineNo;
698     try {
699       parseLineSpec(SecondLineSpec, EndFile, EndLineNo);
700     } catch (...) {
701       LineListedEnd = SavedLLE;
702       throw;
703     }
704
705     // Inherit file specified by the first line spec if there was one.
706     if (EndFile == 0) EndFile = StartFile;
707
708     if (StartFile != EndFile)
709       throw "Start and end line specifiers are in different files!";
710     CurrentFile = StartFile;
711     StartLine = StartLineNo;
712     EndLine = EndLineNo+1;
713   }
714
715   assert((int)StartLine > 0 && (int)EndLine > 0 && StartLine <= EndLine &&
716          "Error reading line specifiers!");
717
718   // If there was no current file, and the user didn't specify one to list, we
719   // have an error.
720   if (CurrentFile == 0)
721     throw "There is no current file to list.";
722
723   // Remember for next time.
724   LineListedStart = StartLine;
725   LineListedEnd = StartLine;
726
727   for (unsigned LineNo = StartLine; LineNo != EndLine; ++LineNo) {
728     // Print the source line, unless it is invalid.
729     if (printSourceLine(LineNo))
730       break;
731     LineListedEnd = LineNo+1;
732   }
733
734   // If we didn't print any lines, find out why.
735   if (LineListedEnd == StartLine) {
736     // See if we can read line #0 from the file, if not, we couldn't load the
737     // file.
738     const char *LineStart, *LineEnd;
739     CurrentFile->getSourceLine(0, LineStart, LineEnd);
740     if (LineStart == 0)
741       throw "Could not load source file '" + CurrentFile->getFilename() + "'!";
742     else
743       std::cout << "<end of file>\n";
744   }
745 }
746
747 void CLIDebugger::setCommand(std::string &Options) {
748   std::string What = getToken(Options);
749
750   if (What.empty())
751     throw "set command expects at least two arguments.";
752   if (What == "args") {
753     parseProgramOptions(Options);
754   } else if (What == "language") {
755     std::string Lang = getToken(Options);
756     if (!getToken(Options).empty())
757       throw "set language expects one argument at most.";
758     if (Lang == "") {
759       std::cout << "The currently understood settings are:\n\n"
760                 << "local or auto  Automatic setting based on source file\n"
761                 << "c              Use the C language\n"
762                 << "c++            Use the C++ language\n"
763                 << "unknown        Use when source language is not supported\n";
764     } else if (Lang == "local" || Lang == "auto") {
765       CurrentLanguage = 0;
766     } else if (Lang == "c") {
767       CurrentLanguage = &SourceLanguage::getCFamilyInstance();
768     } else if (Lang == "c++") {
769       CurrentLanguage = &SourceLanguage::getCPlusPlusInstance();
770     } else if (Lang == "unknown") {
771       CurrentLanguage = &SourceLanguage::getUnknownLanguageInstance();
772     } else {
773       throw "Unknown language '" + Lang + "'.";
774     }
775
776   } else if (What == "listsize") {
777     ListSize = getUnsignedIntegerOption("'set prompt' command", Options);
778   } else if (What == "prompt") {
779     // Include any trailing whitespace or other tokens, but not leading
780     // whitespace.
781     Prompt = getToken(Options);  // Strip leading whitespace
782     Prompt += Options;           // Keep trailing whitespace or other stuff
783   } else {
784     // FIXME: Try to parse this as a source-language program expression.
785     throw "Don't know how to set '" + What + "'!";
786   }
787 }
788
789 void CLIDebugger::showCommand(std::string &Options) {
790   std::string What = getToken(Options);
791
792   if (What.empty() || !getToken(Options).empty())
793     throw "show command expects one argument.";
794
795   if (What == "args") {
796     std::cout << "Argument list to give program when started is \"";
797     // FIXME: This doesn't print stuff correctly if the arguments have spaces in
798     // them, but currently the only way to get that is to use the --args command
799     // line argument.  This should really handle escaping all hard characters as
800     // needed.
801     for (unsigned i = 0, e = Dbg.getNumProgramArguments(); i != e; ++i)
802       std::cout << (i ? " " : "") << Dbg.getProgramArgument(i);
803     std::cout << "\"\n";
804
805   } else if (What == "language") {
806     std::cout << "The current source language is '";
807     if (CurrentLanguage)
808       std::cout << CurrentLanguage->getSourceLanguageName();
809     else
810       std::cout << "auto; currently "
811                 << getCurrentLanguage().getSourceLanguageName();
812     std::cout << "'.\n";
813   } else if (What == "listsize") {
814     std::cout << "Number of source lines llvm-db will list by default is "
815               << ListSize << ".\n";
816   } else if (What == "prompt") {
817     std::cout << "llvm-db's prompt is \"" << Prompt << "\".\n";
818   } else {
819     throw "Unknown show command '" + What + "'.  Try 'help show'.";
820   }
821 }
822
823 void CLIDebugger::helpCommand(std::string &Options) {
824   // Print out all of the commands in the CommandTable
825   std::string Command = getToken(Options);
826   if (!getToken(Options).empty())
827     throw "help command takes at most one argument.";
828
829   // Getting detailed help on a particular command?
830   if (!Command.empty()) {
831     CLICommand *C = getCommand(Command);
832     std::cout << C->getShortHelp() << ".\n" << C->getLongHelp();
833
834     // If there are aliases for this option, print them out.
835     const std::vector<std::string> &Names = C->getOptionNames();
836     if (Names.size() > 1) {
837       std::cout << "The '" << Command << "' command is known as: '"
838                 << Names[0] << "'";
839       for (unsigned i = 1, e = Names.size(); i != e; ++i)
840         std::cout << ", '" << Names[i] << "'";
841       std::cout << "\n";
842     }
843
844   } else {
845     unsigned MaxSize = 0;
846     for (std::map<std::string, CLICommand*>::iterator I = CommandTable.begin(),
847            E = CommandTable.end(); I != E; ++I)
848       if (I->first.size() > MaxSize &&
849           I->first == I->second->getPrimaryOptionName())
850         MaxSize = I->first.size();
851
852     // Loop over all of the commands, printing the short help version
853     for (std::map<std::string, CLICommand*>::iterator I = CommandTable.begin(),
854            E = CommandTable.end(); I != E; ++I)
855       if (I->first == I->second->getPrimaryOptionName())
856         std::cout << I->first << std::string(MaxSize - I->first.size(), ' ')
857                   << " - " << I->second->getShortHelp() << "\n";
858   }
859 }