blob: cfb53e0ad34528ad15414c067f6bc9918c5d88d6 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectSourceFile.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 "CommandObjectSourceFile.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000016#include "lldb/Interpreter/Args.h"
Greg Clayton63094e02010-06-23 01:19:29 +000017#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Interpreter/CommandInterpreter.h"
19#include "lldb/Interpreter/CommandReturnObject.h"
20#include "lldb/Target/Process.h"
21#include "lldb/Core/SourceManager.h"
22#include "lldb/Target/TargetList.h"
23#include "lldb/Interpreter/CommandCompletions.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
28CommandObjectSourceFile::CommandOptions::CommandOptions () :
29 Options()
30{
31}
32
33CommandObjectSourceFile::CommandOptions::~CommandOptions ()
34{
35}
36
37Error
38CommandObjectSourceFile::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
39{
40 Error error;
41 const char short_option = g_option_table[option_idx].short_option;
42 switch (short_option)
43 {
44 case 'l':
45 start_line = Args::StringToUInt32 (option_arg, 0);
46 if (start_line == 0)
47 error.SetErrorStringWithFormat("Invalid line number: '%s'.\n", option_arg);
48 break;
49
50 case 'n':
51 num_lines = Args::StringToUInt32 (option_arg, 0);
52 if (num_lines == 0)
53 error.SetErrorStringWithFormat("Invalid line count: '%s'.\n", option_arg);
54 break;
55
56 case 'f':
57 file_name = option_arg;
58 break;
59
60 default:
61 error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
62 break;
63 }
64
65 return error;
66}
67
68void
69CommandObjectSourceFile::CommandOptions::ResetOptionValues ()
70{
71 Options::ResetOptionValues();
72
73 file_spec.Clear();
74 file_name.clear();
75 start_line = 0;
76 num_lines = 10;
77}
78
79const lldb::OptionDefinition*
80CommandObjectSourceFile::CommandOptions::GetDefinitions ()
81{
82 return g_option_table;
83}
84
85lldb::OptionDefinition
86CommandObjectSourceFile::CommandOptions::g_option_table[] =
87{
Jim Ingham34e9a982010-06-15 18:47:14 +000088{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, "<line>", "The line number at which to start the display source."},
89{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<file>", "The file from which to display source."},
90{ LLDB_OPT_SET_1, false, "count", 'n', required_argument, NULL, 0, "<count>", "The number of source lines to display."},
Chris Lattner24943d22010-06-08 16:52:24 +000091{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
92};
93
94
95
96//-------------------------------------------------------------------------
97// CommandObjectSourceFile
98//-------------------------------------------------------------------------
99
100CommandObjectSourceFile::CommandObjectSourceFile() :
101 CommandObject ("source-file",
102 "Display source files from the current executable's debug info.",
103 "source-file [<cmd-options>] [<filename>]")
104{
105}
106
107CommandObjectSourceFile::~CommandObjectSourceFile ()
108{
109}
110
111
112Options *
113CommandObjectSourceFile::GetOptions ()
114{
115 return &m_options;
116}
117
118
119bool
120CommandObjectSourceFile::Execute
121(
Greg Clayton63094e02010-06-23 01:19:29 +0000122 CommandInterpreter &interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000123 Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000124 CommandReturnObject &result
125)
126{
127 const int argc = args.GetArgumentCount();
128
129 if (argc != 0)
130 {
131 result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName());
132 result.SetStatus (eReturnStatusFailed);
133 }
134
Greg Clayton63094e02010-06-23 01:19:29 +0000135 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000136 if (m_options.file_name.empty())
137 {
138 // Last valid source manager context, or the current frame if no
139 // valid last context in source manager.
140 // One little trick here, if you type the exact same list command twice in a row, it is
141 // more likely because you typed it once, then typed it again
142 if (m_options.start_line == 0)
143 {
Greg Clayton63094e02010-06-23 01:19:29 +0000144 if (interpreter.GetDebugger().GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream()))
Chris Lattner24943d22010-06-08 16:52:24 +0000145 {
146 result.SetStatus (eReturnStatusSuccessFinishResult);
147 }
148 }
149 else
150 {
Greg Clayton63094e02010-06-23 01:19:29 +0000151 if (interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile(
Chris Lattner24943d22010-06-08 16:52:24 +0000152 m_options.start_line, // Line to display
153 0, // Lines before line to display
154 m_options.num_lines, // Lines after line to display
155 "", // Don't mark "line"
156 &result.GetOutputStream()))
157 {
158 result.SetStatus (eReturnStatusSuccessFinishResult);
159 }
160
161 }
162 }
163 else
164 {
165 const char *filename = m_options.file_name.c_str();
Greg Clayton63094e02010-06-23 01:19:29 +0000166 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000167 if (target == NULL)
168 {
169 result.AppendError ("invalid target, set executable file using 'file' command");
170 result.SetStatus (eReturnStatusFailed);
171 return false;
172 }
173
174
175 bool check_inlines = false;
176 SymbolContextList sc_list;
177 size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
178 0,
179 check_inlines,
180 eSymbolContextModule | eSymbolContextCompUnit,
181 sc_list);
182 if (num_matches > 0)
183 {
184 SymbolContext sc;
185 if (sc_list.GetContextAtIndex(0, sc))
186 {
187 if (sc.comp_unit)
188 {
Greg Clayton63094e02010-06-23 01:19:29 +0000189 interpreter.GetDebugger().GetSourceManager ().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
190 m_options.start_line, // Line to display
191 0, // Lines before line to display
192 m_options.num_lines, // Lines after line to display
193 "", // Don't mark "line"
194 &result.GetOutputStream());
195
Chris Lattner24943d22010-06-08 16:52:24 +0000196 result.SetStatus (eReturnStatusSuccessFinishResult);
197
198 }
199 }
200 }
201 }
202
203 return result.Succeeded();
204}
205