1 //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CommandObjectSource.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Interpreter/Args.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/CommandReturnObject.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/TargetList.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 const char *k_space_characters = "\t\n\v\f\r ";
27 
28 //-------------------------------------------------------------------------
29 // CommandObjectSource
30 //-------------------------------------------------------------------------
31 
32 CommandObjectSource::CommandObjectSource() :
33     CommandObject ("source",
34                    "Reads in debugger commands from the file <filename> and executes them.",
35                    "source <filename>")
36 {
37 }
38 
39 CommandObjectSource::~CommandObjectSource ()
40 {
41 }
42 
43 bool
44 CommandObjectSource::Execute
45 (
46     CommandInterpreter &interpreter,
47     Args& args,
48     CommandReturnObject &result
49 )
50 {
51     const int argc = args.GetArgumentCount();
52     if (argc == 1)
53     {
54         const char *filename = args.GetArgumentAtIndex(0);
55         bool success = true;
56 
57         result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
58 
59         FileSpec cmd_file (filename);
60         if (cmd_file.Exists())
61         {
62             STLStringArray commands;
63             success = cmd_file.ReadFileLines (commands);
64 
65             STLStringArray::iterator pos = commands.begin();
66 
67             // Trim out any empty lines or lines that start with the comment
68             // char '#'
69             while (pos != commands.end())
70             {
71                 bool remove_string = false;
72                 size_t non_space = pos->find_first_not_of (k_space_characters);
73                 if (non_space == std::string::npos)
74                     remove_string = true; // Empty line
75                 else if ((*pos)[non_space] == '#')
76                     remove_string = true; // Comment line that starts with '#'
77 
78                 if (remove_string)
79                     pos = commands.erase(pos);
80                 else
81                     ++pos;
82             }
83 
84             if (commands.size() > 0)
85             {
86                 const size_t num_commands = commands.size();
87                 size_t i;
88                 for (i = 0; i<num_commands; ++i)
89                 {
90                     result.GetOutputStream().Printf("%s %s\n", interpreter.GetPrompt(), commands[i].c_str());
91                     if (!interpreter.HandleCommand(commands[i].c_str(), false, result))
92                         break;
93                 }
94 
95                 if (i < num_commands)
96                 {
97                     result.AppendErrorWithFormat("Aborting source of '%s' after command '%s' failed.\n", filename, commands[i].c_str());
98                     result.SetStatus (eReturnStatusSuccessFinishResult);
99                 }
100                 else
101                 {
102                     success = true;
103                     result.SetStatus (eReturnStatusFailed);
104                 }
105             }
106         }
107         else
108         {
109             result.AppendErrorWithFormat ("File '%s' does not exist.\n", filename);
110             result.SetStatus (eReturnStatusFailed);
111             success = false;
112         }
113 
114         if (success)
115         {
116             result.SetStatus (eReturnStatusSuccessFinishNoResult);
117         }
118     }
119     else
120     {
121         result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
122         result.SetStatus (eReturnStatusFailed);
123     }
124     return result.Succeeded();
125 
126 }
127