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