blob: 2fd0f9c7b284fc75330f44a484affa8eb6f877b2 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
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"
Jim Ingham767af882010-07-07 03:36:20 +000020#include "lldb/Core/FileSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Target/Process.h"
Jim Ingham767af882010-07-07 03:36:20 +000022#include "lldb/Core/SourceManager.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Target/TargetList.h"
Jim Ingham767af882010-07-07 03:36:20 +000024#include "lldb/Interpreter/CommandCompletions.h"
25#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026
27using namespace lldb;
28using namespace lldb_private;
29
Chris Lattner24943d22010-06-08 16:52:24 +000030//-------------------------------------------------------------------------
Jim Ingham767af882010-07-07 03:36:20 +000031// CommandObjectSourceList
Chris Lattner24943d22010-06-08 16:52:24 +000032//-------------------------------------------------------------------------
33
Jim Ingham767af882010-07-07 03:36:20 +000034class CommandObjectSourceInfo : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +000035{
Chris Lattner24943d22010-06-08 16:52:24 +000036
Jim Ingham767af882010-07-07 03:36:20 +000037 class CommandOptions : public Options
Chris Lattner24943d22010-06-08 16:52:24 +000038 {
Jim Ingham767af882010-07-07 03:36:20 +000039 public:
40 CommandOptions () :
41 Options()
Chris Lattner24943d22010-06-08 16:52:24 +000042 {
Jim Ingham767af882010-07-07 03:36:20 +000043 }
Chris Lattner24943d22010-06-08 16:52:24 +000044
Jim Ingham767af882010-07-07 03:36:20 +000045 ~CommandOptions ()
46 {
47 }
Chris Lattner24943d22010-06-08 16:52:24 +000048
Jim Ingham767af882010-07-07 03:36:20 +000049 Error
50 SetOptionValue (int option_idx, const char *option_arg)
51 {
52 Error error;
53 const char short_option = g_option_table[option_idx].short_option;
54 switch (short_option)
Chris Lattner24943d22010-06-08 16:52:24 +000055 {
Jim Ingham767af882010-07-07 03:36:20 +000056 case 'l':
57 start_line = Args::StringToUInt32 (option_arg, 0);
58 if (start_line == 0)
59 error.SetErrorStringWithFormat("Invalid line number: '%s'.\n", option_arg);
60 break;
Chris Lattner24943d22010-06-08 16:52:24 +000061
Jim Ingham767af882010-07-07 03:36:20 +000062 case 'f':
63 file_name = option_arg;
64 break;
65
66 default:
67 error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
68 break;
Chris Lattner24943d22010-06-08 16:52:24 +000069 }
70
Jim Ingham767af882010-07-07 03:36:20 +000071 return error;
72 }
Chris Lattner24943d22010-06-08 16:52:24 +000073
Jim Ingham767af882010-07-07 03:36:20 +000074 void
75 ResetOptionValues ()
76 {
77 Options::ResetOptionValues();
78
79 file_spec.Clear();
80 file_name.clear();
81 start_line = 0;
82 }
83
84 const lldb::OptionDefinition*
85 GetDefinitions ()
86 {
87 return g_option_table;
88 }
89 static lldb::OptionDefinition g_option_table[];
90
91 // Instance variables to hold the values for command options.
92 FileSpec file_spec;
93 std::string file_name;
94 uint32_t start_line;
95
96 };
97
98public:
99 CommandObjectSourceInfo() :
100 CommandObject ("source info",
101 "Display info on the source lines from the current executable's debug info.",
102 "source info [<cmd-options>]")
103 {
104 }
105
106 ~CommandObjectSourceInfo ()
107 {
108 }
109
110
111 Options *
112 GetOptions ()
113 {
114 return &m_options;
115 }
116
117
118 bool
119 Execute
120 (
121 CommandInterpreter &interpreter,
122 Args& args,
123 CommandReturnObject &result
124 )
125 {
126 result.AppendError ("Not yet implemented");
127 result.SetStatus (eReturnStatusFailed);
128 return false;
129 }
130protected:
131 CommandOptions m_options;
132};
133
134lldb::OptionDefinition
135CommandObjectSourceInfo::CommandOptions::g_option_table[] =
136{
137{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, "<line>", "The line number at which to start the display source."},
138{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<file>", "The file from which to display source."},
139{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
140};
141
142#pragma mark CommandObjectSourceList
143//-------------------------------------------------------------------------
144// CommandObjectSourceList
145//-------------------------------------------------------------------------
146
147class CommandObjectSourceList : public CommandObject
148{
149
150 class CommandOptions : public Options
151 {
152 public:
153 CommandOptions () :
154 Options()
155 {
156 }
157
158 ~CommandOptions ()
159 {
160 }
161
162 Error
163 SetOptionValue (int option_idx, const char *option_arg)
164 {
165 Error error;
166 const char short_option = g_option_table[option_idx].short_option;
167 switch (short_option)
168 {
169 case 'l':
170 start_line = Args::StringToUInt32 (option_arg, 0);
171 if (start_line == 0)
172 error.SetErrorStringWithFormat("Invalid line number: '%s'.\n", option_arg);
173 break;
174
175 case 'n':
176 num_lines = Args::StringToUInt32 (option_arg, 0);
177 if (num_lines == 0)
178 error.SetErrorStringWithFormat("Invalid line count: '%s'.\n", option_arg);
179 break;
180
181 case 'f':
182 file_name = option_arg;
183 break;
184
185 default:
186 error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
187 break;
188 }
189
190 return error;
191 }
192
193 void
194 ResetOptionValues ()
195 {
196 Options::ResetOptionValues();
197
198 file_spec.Clear();
199 file_name.clear();
200 start_line = 0;
201 num_lines = 10;
202 }
203
204 const lldb::OptionDefinition*
205 GetDefinitions ()
206 {
207 return g_option_table;
208 }
209 static lldb::OptionDefinition g_option_table[];
210
211 // Instance variables to hold the values for command options.
212 FileSpec file_spec;
213 std::string file_name;
214 uint32_t start_line;
215 uint32_t num_lines;
216
217 };
218
219public:
220 CommandObjectSourceList() :
221 CommandObject ("source list",
222 "Display source files from the current executable's debug info.",
223 "source list [<cmd-options>] [<filename>]")
224 {
225 }
226
227 ~CommandObjectSourceList ()
228 {
229 }
230
231
232 Options *
233 GetOptions ()
234 {
235 return &m_options;
236 }
237
238
239 bool
240 Execute
241 (
242 CommandInterpreter &interpreter,
243 Args& args,
244 CommandReturnObject &result
245 )
246 {
247 const int argc = args.GetArgumentCount();
248
249 if (argc != 0)
250 {
251 result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName());
252 result.SetStatus (eReturnStatusFailed);
253 }
254
255 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
256 if (m_options.file_name.empty())
257 {
258 // Last valid source manager context, or the current frame if no
259 // valid last context in source manager.
260 // One little trick here, if you type the exact same list command twice in a row, it is
261 // more likely because you typed it once, then typed it again
262 if (m_options.start_line == 0)
263 {
264 if (interpreter.GetDebugger().GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream()))
Chris Lattner24943d22010-06-08 16:52:24 +0000265 {
Chris Lattner24943d22010-06-08 16:52:24 +0000266 result.SetStatus (eReturnStatusSuccessFinishResult);
267 }
Jim Ingham767af882010-07-07 03:36:20 +0000268 }
269 else
270 {
271 if (interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile(
272 m_options.start_line, // Line to display
273 0, // Lines before line to display
274 m_options.num_lines, // Lines after line to display
275 "", // Don't mark "line"
276 &result.GetOutputStream()))
Chris Lattner24943d22010-06-08 16:52:24 +0000277 {
Jim Ingham767af882010-07-07 03:36:20 +0000278 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000279 }
Jim Ingham767af882010-07-07 03:36:20 +0000280
Chris Lattner24943d22010-06-08 16:52:24 +0000281 }
282 }
283 else
284 {
Jim Ingham767af882010-07-07 03:36:20 +0000285 const char *filename = m_options.file_name.c_str();
286 Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
287 if (target == NULL)
288 {
289 result.AppendError ("invalid target, set executable file using 'file' command");
290 result.SetStatus (eReturnStatusFailed);
291 return false;
292 }
293
294
295 bool check_inlines = false;
296 SymbolContextList sc_list;
297 size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
298 0,
299 check_inlines,
300 eSymbolContextModule | eSymbolContextCompUnit,
301 sc_list);
302 if (num_matches > 0)
303 {
304 SymbolContext sc;
305 if (sc_list.GetContextAtIndex(0, sc))
306 {
307 if (sc.comp_unit)
308 {
309 interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
310 m_options.start_line, // Line to display
311 0, // Lines before line to display
312 m_options.num_lines, // Lines after line to display
313 "", // Don't mark "line"
314 &result.GetOutputStream());
315
316 result.SetStatus (eReturnStatusSuccessFinishResult);
317
318 }
319 }
320 }
Chris Lattner24943d22010-06-08 16:52:24 +0000321 }
322
Jim Ingham767af882010-07-07 03:36:20 +0000323 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +0000324 }
Jim Ingham767af882010-07-07 03:36:20 +0000325
326 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
Chris Lattner24943d22010-06-08 16:52:24 +0000327 {
Jim Ingham767af882010-07-07 03:36:20 +0000328 return m_cmd_name.c_str();
Chris Lattner24943d22010-06-08 16:52:24 +0000329 }
Chris Lattner24943d22010-06-08 16:52:24 +0000330
Jim Ingham767af882010-07-07 03:36:20 +0000331protected:
332 CommandOptions m_options;
333
334};
335
336lldb::OptionDefinition
337CommandObjectSourceList::CommandOptions::g_option_table[] =
338{
339{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, "<line>", "The line number at which to start the display source."},
340{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<file>", "The file from which to display source."},
341{ LLDB_OPT_SET_1, false, "count", 'n', required_argument, NULL, 0, "<count>", "The number of source lines to display."},
342{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
343};
344
345#pragma mark CommandObjectMultiwordSource
346
347//-------------------------------------------------------------------------
348// CommandObjectMultiwordSource
349//-------------------------------------------------------------------------
350
351CommandObjectMultiwordSource::CommandObjectMultiwordSource (CommandInterpreter &interpreter) :
352 CommandObjectMultiword ("source",
353 "Commands for accessing source file information",
354 "source <subcommand> [<subcommand-options>]")
355{
356 LoadSubCommand (interpreter, "info", CommandObjectSP (new CommandObjectSourceInfo ()));
357 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectSourceList ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000358}
Jim Ingham767af882010-07-07 03:36:20 +0000359
360CommandObjectMultiwordSource::~CommandObjectMultiwordSource ()
361{
362}
363