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/Core/Args.h"
17 #include "lldb/Interpreter/CommandContext.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     Args& args,
47     CommandContext *context,
48     CommandInterpreter *interpreter,
49     CommandReturnObject &result
50 )
51 {
52     const int argc = args.GetArgumentCount();
53     if (argc == 1)
54     {
55         const char *filename = args.GetArgumentAtIndex(0);
56         bool success = true;
57 
58         result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
59 
60         FileSpec cmd_file (filename);
61         if (cmd_file.Exists())
62         {
63             STLStringArray commands;
64             success = cmd_file.ReadFileLines (commands);
65 
66             STLStringArray::iterator pos = commands.begin();
67 
68             // Trim out any empty lines or lines that start with the comment
69             // char '#'
70             while (pos != commands.end())
71             {
72                 bool remove_string = false;
73                 size_t non_space = pos->find_first_not_of (k_space_characters);
74                 if (non_space == std::string::npos)
75                     remove_string = true; // Empty line
76                 else if ((*pos)[non_space] == '#')
77                     remove_string = true; // Comment line that starts with '#'
78 
79                 if (remove_string)
80                     pos = commands.erase(pos);
81                 else
82                     ++pos;
83             }
84 
85             if (commands.size() > 0)
86             {
87                 const size_t num_commands = commands.size();
88                 size_t i;
89                 for (i = 0; i<num_commands; ++i)
90                 {
91                     result.GetOutputStream().Printf("%s %s\n", interpreter->GetPrompt(), commands[i].c_str());
92                     if (!interpreter->HandleCommand(commands[i].c_str(), false, result))
93                         break;
94                 }
95 
96                 if (i < num_commands)
97                 {
98                     result.AppendErrorWithFormat("Aborting source of '%s' after command '%s' failed.\n", filename, commands[i].c_str());
99                     result.SetStatus (eReturnStatusSuccessFinishResult);
100                 }
101                 else
102                 {
103                     success = true;
104                     result.SetStatus (eReturnStatusFailed);
105                 }
106             }
107         }
108         else
109         {
110             result.AppendErrorWithFormat ("File '%s' does not exist.\n", filename);
111             result.SetStatus (eReturnStatusFailed);
112             success = false;
113         }
114 
115         if (success)
116         {
117             result.SetStatus (eReturnStatusSuccessFinishNoResult);
118         }
119     }
120     else
121     {
122         result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
123         result.SetStatus (eReturnStatusFailed);
124     }
125     return result.Succeeded();
126 
127 }
128