blob: 6f95bd7a276d75654865a37f03007bb404c43e71 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Debugger.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
Greg Clayton4a33d312011-06-23 17:59:56 +000010#include "lldb/Core/Debugger.h"
11
12#include <map>
13
Enrico Granata4becb372011-06-29 22:27:15 +000014#include "clang/AST/DeclCXX.h"
15#include "clang/AST/Type.h"
16
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/lldb-private.h"
18#include "lldb/Core/ConnectionFileDescriptor.h"
Greg Clayton4a33d312011-06-23 17:59:56 +000019#include "lldb/Core/FormatManager.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/InputReader.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000021#include "lldb/Core/RegisterValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/State.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000023#include "lldb/Core/StreamAsynchronousIO.h"
Greg Clayton1b654882010-09-19 02:33:57 +000024#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
Enrico Granata4becb372011-06-29 22:27:15 +000026#include "lldb/Core/ValueObject.h"
Greg Claytona3406612011-02-07 23:24:47 +000027#include "lldb/Host/Terminal.h"
Greg Clayton66111032010-06-23 01:19:29 +000028#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/TargetList.h"
30#include "lldb/Target/Process.h"
Greg Clayton1b654882010-09-19 02:33:57 +000031#include "lldb/Target/RegisterContext.h"
32#include "lldb/Target/StopInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Target/Thread.h"
Greg Clayton5a314712011-10-14 07:41:33 +000034#include "lldb/Utility/AnsiTerminal.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
36using namespace lldb;
37using namespace lldb_private;
38
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
Greg Clayton1b654882010-09-19 02:33:57 +000040static uint32_t g_shared_debugger_refcount = 0;
Caroline Ticeebc1bb22010-06-30 16:22:25 +000041static lldb::user_id_t g_unique_id = 1;
42
Greg Clayton1b654882010-09-19 02:33:57 +000043#pragma mark Static Functions
44
45static Mutex &
46GetDebuggerListMutex ()
47{
48 static Mutex g_mutex(Mutex::eMutexTypeRecursive);
49 return g_mutex;
50}
51
52typedef std::vector<DebuggerSP> DebuggerList;
53
54static DebuggerList &
55GetDebuggerList()
56{
57 // hide the static debugger list inside a singleton accessor to avoid
58 // global init contructors
59 static DebuggerList g_list;
60 return g_list;
61}
62
63
64#pragma mark Debugger
65
Greg Clayton99d0faf2010-11-18 23:32:35 +000066UserSettingsControllerSP &
67Debugger::GetSettingsController ()
68{
69 static UserSettingsControllerSP g_settings_controller;
70 return g_settings_controller;
71}
72
Caroline Tice2f88aad2011-01-14 00:29:16 +000073int
74Debugger::TestDebuggerRefCount ()
75{
76 return g_shared_debugger_refcount;
77}
78
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079void
80Debugger::Initialize ()
81{
Greg Clayton66111032010-06-23 01:19:29 +000082 if (g_shared_debugger_refcount == 0)
Greg Clayton99d0faf2010-11-18 23:32:35 +000083 {
Greg Claytondbe54502010-11-19 03:46:01 +000084 lldb_private::Initialize();
Greg Clayton99d0faf2010-11-18 23:32:35 +000085 }
Greg Clayton66111032010-06-23 01:19:29 +000086 g_shared_debugger_refcount++;
Greg Clayton99d0faf2010-11-18 23:32:35 +000087
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088}
89
90void
91Debugger::Terminate ()
92{
Greg Clayton66111032010-06-23 01:19:29 +000093 if (g_shared_debugger_refcount > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094 {
Greg Clayton66111032010-06-23 01:19:29 +000095 g_shared_debugger_refcount--;
96 if (g_shared_debugger_refcount == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097 {
Greg Claytondbe54502010-11-19 03:46:01 +000098 lldb_private::WillTerminate();
99 lldb_private::Terminate();
Caroline Tice6760a512011-01-17 21:55:19 +0000100
101 // Clear our master list of debugger objects
102 Mutex::Locker locker (GetDebuggerListMutex ());
103 GetDebuggerList().clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 }
106}
107
Caroline Tice20bd37f2011-03-10 22:14:10 +0000108void
109Debugger::SettingsInitialize ()
110{
111 static bool g_initialized = false;
112
113 if (!g_initialized)
114 {
115 g_initialized = true;
116 UserSettingsControllerSP &usc = GetSettingsController();
117 usc.reset (new SettingsController);
118 UserSettingsController::InitializeSettingsController (usc,
119 SettingsController::global_settings_table,
120 SettingsController::instance_settings_table);
121 // Now call SettingsInitialize for each settings 'child' of Debugger
122 Target::SettingsInitialize ();
123 }
124}
125
126void
127Debugger::SettingsTerminate ()
128{
129
130 // Must call SettingsTerminate() for each settings 'child' of Debugger, before terminating the Debugger's
131 // Settings.
132
133 Target::SettingsTerminate ();
134
135 // Now terminate the Debugger Settings.
136
137 UserSettingsControllerSP &usc = GetSettingsController();
138 UserSettingsController::FinalizeSettingsController (usc);
139 usc.reset();
140}
141
Greg Clayton66111032010-06-23 01:19:29 +0000142DebuggerSP
143Debugger::CreateInstance ()
144{
145 DebuggerSP debugger_sp (new Debugger);
146 // Scope for locker
147 {
148 Mutex::Locker locker (GetDebuggerListMutex ());
149 GetDebuggerList().push_back(debugger_sp);
150 }
151 return debugger_sp;
152}
153
Caroline Ticee02657b2011-01-22 01:02:07 +0000154void
Greg Clayton4d122c42011-09-17 08:33:22 +0000155Debugger::Destroy (DebuggerSP &debugger_sp)
Caroline Ticee02657b2011-01-22 01:02:07 +0000156{
157 if (debugger_sp.get() == NULL)
158 return;
159
Jim Ingham8314c522011-09-15 21:36:42 +0000160 debugger_sp->Clear();
161
Caroline Ticee02657b2011-01-22 01:02:07 +0000162 Mutex::Locker locker (GetDebuggerListMutex ());
163 DebuggerList &debugger_list = GetDebuggerList ();
164 DebuggerList::iterator pos, end = debugger_list.end();
165 for (pos = debugger_list.begin (); pos != end; ++pos)
166 {
167 if ((*pos).get() == debugger_sp.get())
168 {
169 debugger_list.erase (pos);
170 return;
171 }
172 }
Caroline Ticee02657b2011-01-22 01:02:07 +0000173}
174
Greg Clayton4d122c42011-09-17 08:33:22 +0000175DebuggerSP
Greg Clayton66111032010-06-23 01:19:29 +0000176Debugger::GetSP ()
177{
Greg Clayton4d122c42011-09-17 08:33:22 +0000178 // This object contains an instrusive ref count base class so we can
179 // easily make a shared pointer to this object
180 return DebuggerSP (this);
Greg Clayton66111032010-06-23 01:19:29 +0000181}
182
Greg Clayton4d122c42011-09-17 08:33:22 +0000183DebuggerSP
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000184Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
185{
Greg Clayton4d122c42011-09-17 08:33:22 +0000186 DebuggerSP debugger_sp;
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000187
188 Mutex::Locker locker (GetDebuggerListMutex ());
189 DebuggerList &debugger_list = GetDebuggerList();
190 DebuggerList::iterator pos, end = debugger_list.end();
191
192 for (pos = debugger_list.begin(); pos != end; ++pos)
193 {
194 if ((*pos).get()->m_instance_name == instance_name)
195 {
196 debugger_sp = *pos;
197 break;
198 }
199 }
200 return debugger_sp;
201}
Greg Clayton66111032010-06-23 01:19:29 +0000202
203TargetSP
204Debugger::FindTargetWithProcessID (lldb::pid_t pid)
205{
Greg Clayton4d122c42011-09-17 08:33:22 +0000206 TargetSP target_sp;
Greg Clayton66111032010-06-23 01:19:29 +0000207 Mutex::Locker locker (GetDebuggerListMutex ());
208 DebuggerList &debugger_list = GetDebuggerList();
209 DebuggerList::iterator pos, end = debugger_list.end();
210 for (pos = debugger_list.begin(); pos != end; ++pos)
211 {
212 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
213 if (target_sp)
214 break;
215 }
216 return target_sp;
217}
218
Greg Claytone4e45922011-11-16 05:37:56 +0000219TargetSP
220Debugger::FindTargetWithProcess (Process *process)
221{
222 TargetSP target_sp;
223 Mutex::Locker locker (GetDebuggerListMutex ());
224 DebuggerList &debugger_list = GetDebuggerList();
225 DebuggerList::iterator pos, end = debugger_list.end();
226 for (pos = debugger_list.begin(); pos != end; ++pos)
227 {
228 target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
229 if (target_sp)
230 break;
231 }
232 return target_sp;
233}
234
Greg Clayton66111032010-06-23 01:19:29 +0000235
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236Debugger::Debugger () :
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000237 UserID (g_unique_id++),
Greg Claytondbe54502010-11-19 03:46:01 +0000238 DebuggerInstanceSettings (*GetSettingsController()),
Greg Claytond46c87a2010-12-04 02:39:47 +0000239 m_input_comm("debugger.input"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240 m_input_file (),
241 m_output_file (),
242 m_error_file (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 m_target_list (),
Greg Claytonded470d2011-03-19 01:12:21 +0000244 m_platform_list (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 m_listener ("lldb.Debugger"),
Jim Inghame37d6052011-09-13 00:29:56 +0000246 m_source_manager(*this),
247 m_source_file_cache(),
Greg Clayton66111032010-06-23 01:19:29 +0000248 m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000249 m_input_reader_stack (),
Greg Clayton4957bf62010-09-30 21:49:03 +0000250 m_input_reader_data ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251{
Greg Clayton66111032010-06-23 01:19:29 +0000252 m_command_interpreter_ap->Initialize ();
Greg Claytonded470d2011-03-19 01:12:21 +0000253 // Always add our default platform to the platform list
254 PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
255 assert (default_platform_sp.get());
256 m_platform_list.Append (default_platform_sp, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257}
258
259Debugger::~Debugger ()
260{
Jim Ingham8314c522011-09-15 21:36:42 +0000261 Clear();
262}
263
264void
265Debugger::Clear()
266{
Caroline Tice3d6086f2010-12-20 18:35:50 +0000267 CleanUpInputReaders();
Greg Clayton1ed54f52011-10-01 00:45:15 +0000268 m_listener.Clear();
Greg Clayton66111032010-06-23 01:19:29 +0000269 int num_targets = m_target_list.GetNumTargets();
270 for (int i = 0; i < num_targets; i++)
271 {
272 ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
273 if (process_sp)
Jim Ingham8314c522011-09-15 21:36:42 +0000274 {
275 if (process_sp->AttachedToProcess())
276 process_sp->Detach();
277 else
278 process_sp->Destroy();
279 }
Greg Clayton66111032010-06-23 01:19:29 +0000280 }
281 DisconnectInput();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282
Jim Ingham8314c522011-09-15 21:36:42 +0000283}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284
285bool
Greg Claytonfc3f0272011-05-29 04:06:55 +0000286Debugger::GetCloseInputOnEOF () const
287{
288 return m_input_comm.GetCloseOnEOF();
289}
290
291void
292Debugger::SetCloseInputOnEOF (bool b)
293{
294 m_input_comm.SetCloseOnEOF(b);
295}
296
297bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298Debugger::GetAsyncExecution ()
299{
Greg Clayton66111032010-06-23 01:19:29 +0000300 return !m_command_interpreter_ap->GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301}
302
303void
304Debugger::SetAsyncExecution (bool async_execution)
305{
Greg Clayton66111032010-06-23 01:19:29 +0000306 m_command_interpreter_ap->SetSynchronous (!async_execution);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307}
308
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309
310void
311Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
312{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000313 File &in_file = GetInputFile();
314 in_file.SetStream (fh, tranfer_ownership);
315 if (in_file.IsValid() == false)
316 in_file.SetStream (stdin, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317
318 // Disconnect from any old connection if we had one
319 m_input_comm.Disconnect ();
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000320 m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), true));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321 m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
322
323 Error error;
324 if (m_input_comm.StartReadThread (&error) == false)
325 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000326 File &err_file = GetErrorFile();
327
328 err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
329 exit(1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331}
332
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333void
334Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
335{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000336 File &out_file = GetOutputFile();
337 out_file.SetStream (fh, tranfer_ownership);
338 if (out_file.IsValid() == false)
339 out_file.SetStream (stdout, false);
Caroline Tice2f88aad2011-01-14 00:29:16 +0000340
341 GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342}
343
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344void
345Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
346{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000347 File &err_file = GetErrorFile();
348 err_file.SetStream (fh, tranfer_ownership);
349 if (err_file.IsValid() == false)
350 err_file.SetStream (stderr, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351}
352
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353ExecutionContext
Jim Ingham2976d002010-08-26 21:32:51 +0000354Debugger::GetSelectedExecutionContext ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355{
356 ExecutionContext exe_ctx;
Greg Claytonc14ee322011-09-22 04:58:26 +0000357 TargetSP target_sp(GetSelectedTarget());
358 exe_ctx.SetTargetSP (target_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359
360 if (target_sp)
361 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000362 ProcessSP process_sp (target_sp->GetProcessSP());
363 exe_ctx.SetProcessSP (process_sp);
364 if (process_sp && process_sp->IsRunning() == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000366 ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
367 if (thread_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000369 exe_ctx.SetThreadSP (thread_sp);
370 exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
371 if (exe_ctx.GetFramePtr() == NULL)
372 exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 }
374 }
375 }
376 return exe_ctx;
377
378}
379
Caroline Ticeb44880c2011-02-10 01:15:13 +0000380InputReaderSP
381Debugger::GetCurrentInputReader ()
382{
383 InputReaderSP reader_sp;
384
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000385 if (!m_input_reader_stack.IsEmpty())
Caroline Ticeb44880c2011-02-10 01:15:13 +0000386 {
387 // Clear any finished readers from the stack
388 while (CheckIfTopInputReaderIsDone()) ;
389
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000390 if (!m_input_reader_stack.IsEmpty())
391 reader_sp = m_input_reader_stack.Top();
Caroline Ticeb44880c2011-02-10 01:15:13 +0000392 }
393
394 return reader_sp;
395}
396
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397void
398Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
399{
Caroline Ticeefed6132010-11-19 20:47:54 +0000400 if (bytes_len > 0)
401 ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
402 else
403 ((Debugger *)baton)->DispatchInputEndOfFile ();
404}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405
406
407void
408Debugger::DispatchInput (const char *bytes, size_t bytes_len)
409{
Caroline Ticeefed6132010-11-19 20:47:54 +0000410 if (bytes == NULL || bytes_len == 0)
411 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412
413 WriteToDefaultReader (bytes, bytes_len);
414}
415
416void
Caroline Ticeefed6132010-11-19 20:47:54 +0000417Debugger::DispatchInputInterrupt ()
418{
419 m_input_reader_data.clear();
420
Caroline Ticeb44880c2011-02-10 01:15:13 +0000421 InputReaderSP reader_sp (GetCurrentInputReader ());
422 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000423 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000424 reader_sp->Notify (eInputReaderInterrupt);
Caroline Ticeefed6132010-11-19 20:47:54 +0000425
Caroline Ticeb44880c2011-02-10 01:15:13 +0000426 // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
Caroline Ticeefed6132010-11-19 20:47:54 +0000427 while (CheckIfTopInputReaderIsDone ()) ;
428 }
429}
430
431void
432Debugger::DispatchInputEndOfFile ()
433{
434 m_input_reader_data.clear();
435
Caroline Ticeb44880c2011-02-10 01:15:13 +0000436 InputReaderSP reader_sp (GetCurrentInputReader ());
437 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000438 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000439 reader_sp->Notify (eInputReaderEndOfFile);
Caroline Ticeefed6132010-11-19 20:47:54 +0000440
Caroline Ticeb44880c2011-02-10 01:15:13 +0000441 // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
Caroline Ticeefed6132010-11-19 20:47:54 +0000442 while (CheckIfTopInputReaderIsDone ()) ;
443 }
444}
445
446void
Caroline Tice3d6086f2010-12-20 18:35:50 +0000447Debugger::CleanUpInputReaders ()
448{
449 m_input_reader_data.clear();
450
Caroline Ticeb44880c2011-02-10 01:15:13 +0000451 // The bottom input reader should be the main debugger input reader. We do not want to close that one here.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000452 while (m_input_reader_stack.GetSize() > 1)
Caroline Tice3d6086f2010-12-20 18:35:50 +0000453 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000454 InputReaderSP reader_sp (GetCurrentInputReader ());
Caroline Tice3d6086f2010-12-20 18:35:50 +0000455 if (reader_sp)
456 {
457 reader_sp->Notify (eInputReaderEndOfFile);
458 reader_sp->SetIsDone (true);
459 }
460 }
461}
462
463void
Caroline Tice969ed3d2011-05-02 20:41:46 +0000464Debugger::NotifyTopInputReader (InputReaderAction notification)
465{
466 InputReaderSP reader_sp (GetCurrentInputReader());
467 if (reader_sp)
468 {
469 reader_sp->Notify (notification);
470
471 // Flush out any input readers that are done.
472 while (CheckIfTopInputReaderIsDone ())
473 /* Do nothing. */;
474 }
475}
476
Caroline Tice9088b062011-05-09 23:06:58 +0000477bool
Greg Clayton4d122c42011-09-17 08:33:22 +0000478Debugger::InputReaderIsTopReader (const InputReaderSP& reader_sp)
Caroline Tice9088b062011-05-09 23:06:58 +0000479{
Caroline Ticed61c10b2011-06-16 16:27:19 +0000480 InputReaderSP top_reader_sp (GetCurrentInputReader());
Caroline Tice9088b062011-05-09 23:06:58 +0000481
Caroline Ticed61c10b2011-06-16 16:27:19 +0000482 return (reader_sp.get() == top_reader_sp.get());
Caroline Tice9088b062011-05-09 23:06:58 +0000483}
484
485
Caroline Tice969ed3d2011-05-02 20:41:46 +0000486void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
488{
489 if (bytes && bytes_len)
490 m_input_reader_data.append (bytes, bytes_len);
491
492 if (m_input_reader_data.empty())
493 return;
494
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000495 while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497 // Get the input reader from the top of the stack
Caroline Ticeb44880c2011-02-10 01:15:13 +0000498 InputReaderSP reader_sp (GetCurrentInputReader ());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499 if (!reader_sp)
500 break;
501
Greg Clayton471b31c2010-07-20 22:52:08 +0000502 size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000503 m_input_reader_data.size());
504 if (bytes_handled)
505 {
506 m_input_reader_data.erase (0, bytes_handled);
507 }
508 else
509 {
510 // No bytes were handled, we might not have reached our
511 // granularity, just return and wait for more data
512 break;
513 }
514 }
515
Caroline Ticeb44880c2011-02-10 01:15:13 +0000516 // Flush out any input readers that are done.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 while (CheckIfTopInputReaderIsDone ())
518 /* Do nothing. */;
519
520}
521
522void
523Debugger::PushInputReader (const InputReaderSP& reader_sp)
524{
525 if (!reader_sp)
526 return;
Caroline Ticeb44880c2011-02-10 01:15:13 +0000527
528 // Deactivate the old top reader
529 InputReaderSP top_reader_sp (GetCurrentInputReader ());
530
531 if (top_reader_sp)
532 top_reader_sp->Notify (eInputReaderDeactivate);
533
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000534 m_input_reader_stack.Push (reader_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000535 reader_sp->Notify (eInputReaderActivate);
536 ActivateInputReader (reader_sp);
537}
538
539bool
Greg Clayton4d122c42011-09-17 08:33:22 +0000540Debugger::PopInputReader (const InputReaderSP& pop_reader_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541{
542 bool result = false;
543
544 // The reader on the stop of the stack is done, so let the next
545 // read on the stack referesh its prompt and if there is one...
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000546 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000547 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000548 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000549 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550
551 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
552 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000553 m_input_reader_stack.Pop ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000554 reader_sp->Notify (eInputReaderDeactivate);
555 reader_sp->Notify (eInputReaderDone);
556 result = true;
557
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000558 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000559 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000560 reader_sp = m_input_reader_stack.Top();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561 if (reader_sp)
562 {
563 ActivateInputReader (reader_sp);
564 reader_sp->Notify (eInputReaderReactivate);
565 }
566 }
567 }
568 }
569 return result;
570}
571
572bool
573Debugger::CheckIfTopInputReaderIsDone ()
574{
575 bool result = false;
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000576 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000577 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000578 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000579 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580
581 if (reader_sp && reader_sp->IsDone())
582 {
583 result = true;
584 PopInputReader (reader_sp);
585 }
586 }
587 return result;
588}
589
590void
591Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
592{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000593 int input_fd = m_input_file.GetFile().GetDescriptor();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000595 if (input_fd >= 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000597 Terminal tty(input_fd);
Greg Claytona3406612011-02-07 23:24:47 +0000598
599 tty.SetEcho(reader_sp->GetEcho());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600
Greg Claytona3406612011-02-07 23:24:47 +0000601 switch (reader_sp->GetGranularity())
602 {
603 case eInputReaderGranularityByte:
604 case eInputReaderGranularityWord:
605 tty.SetCanonical (false);
606 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607
Greg Claytona3406612011-02-07 23:24:47 +0000608 case eInputReaderGranularityLine:
609 case eInputReaderGranularityAll:
610 tty.SetCanonical (true);
611 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612
Greg Claytona3406612011-02-07 23:24:47 +0000613 default:
614 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615 }
616 }
617}
Greg Clayton66111032010-06-23 01:19:29 +0000618
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000619StreamSP
620Debugger::GetAsyncOutputStream ()
621{
622 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
623 CommandInterpreter::eBroadcastBitAsynchronousOutputData));
624}
625
626StreamSP
627Debugger::GetAsyncErrorStream ()
628{
629 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
630 CommandInterpreter::eBroadcastBitAsynchronousErrorData));
631}
632
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000633DebuggerSP
634Debugger::FindDebuggerWithID (lldb::user_id_t id)
635{
Greg Clayton4d122c42011-09-17 08:33:22 +0000636 DebuggerSP debugger_sp;
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000637
638 Mutex::Locker locker (GetDebuggerListMutex ());
639 DebuggerList &debugger_list = GetDebuggerList();
640 DebuggerList::iterator pos, end = debugger_list.end();
641 for (pos = debugger_list.begin(); pos != end; ++pos)
642 {
643 if ((*pos).get()->GetID() == id)
644 {
645 debugger_sp = *pos;
646 break;
647 }
648 }
649 return debugger_sp;
650}
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000651
Greg Clayton1b654882010-09-19 02:33:57 +0000652static void
653TestPromptFormats (StackFrame *frame)
654{
655 if (frame == NULL)
656 return;
657
658 StreamString s;
659 const char *prompt_format =
660 "{addr = '${addr}'\n}"
661 "{process.id = '${process.id}'\n}"
662 "{process.name = '${process.name}'\n}"
663 "{process.file.basename = '${process.file.basename}'\n}"
664 "{process.file.fullpath = '${process.file.fullpath}'\n}"
665 "{thread.id = '${thread.id}'\n}"
666 "{thread.index = '${thread.index}'\n}"
667 "{thread.name = '${thread.name}'\n}"
668 "{thread.queue = '${thread.queue}'\n}"
669 "{thread.stop-reason = '${thread.stop-reason}'\n}"
670 "{target.arch = '${target.arch}'\n}"
671 "{module.file.basename = '${module.file.basename}'\n}"
672 "{module.file.fullpath = '${module.file.fullpath}'\n}"
673 "{file.basename = '${file.basename}'\n}"
674 "{file.fullpath = '${file.fullpath}'\n}"
675 "{frame.index = '${frame.index}'\n}"
676 "{frame.pc = '${frame.pc}'\n}"
677 "{frame.sp = '${frame.sp}'\n}"
678 "{frame.fp = '${frame.fp}'\n}"
679 "{frame.flags = '${frame.flags}'\n}"
680 "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
681 "{frame.reg.rip = '${frame.reg.rip}'\n}"
682 "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
683 "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
684 "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
685 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
686 "{frame.reg.carp = '${frame.reg.carp}'\n}"
687 "{function.id = '${function.id}'\n}"
688 "{function.name = '${function.name}'\n}"
689 "{function.addr-offset = '${function.addr-offset}'\n}"
690 "{function.line-offset = '${function.line-offset}'\n}"
691 "{function.pc-offset = '${function.pc-offset}'\n}"
692 "{line.file.basename = '${line.file.basename}'\n}"
693 "{line.file.fullpath = '${line.file.fullpath}'\n}"
694 "{line.number = '${line.number}'\n}"
695 "{line.start-addr = '${line.start-addr}'\n}"
696 "{line.end-addr = '${line.end-addr}'\n}"
697;
698
699 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
700 ExecutionContext exe_ctx;
Greg Clayton0603aa92010-10-04 01:05:56 +0000701 frame->CalculateExecutionContext(exe_ctx);
Greg Clayton1b654882010-09-19 02:33:57 +0000702 const char *end = NULL;
703 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
704 {
705 printf("%s\n", s.GetData());
706 }
707 else
708 {
709 printf ("error: at '%s'\n", end);
710 printf ("what we got: %s\n", s.GetData());
711 }
712}
713
Enrico Granata9fc19442011-07-06 02:13:41 +0000714static bool
Enrico Granatadc940732011-08-23 00:32:52 +0000715ScanFormatDescriptor (const char* var_name_begin,
716 const char* var_name_end,
717 const char** var_name_final,
718 const char** percent_position,
Greg Clayton4d122c42011-09-17 08:33:22 +0000719 Format* custom_format,
Enrico Granatadc940732011-08-23 00:32:52 +0000720 ValueObject::ValueObjectRepresentationStyle* val_obj_display)
Enrico Granata9fc19442011-07-06 02:13:41 +0000721{
Enrico Granatae992a082011-07-22 17:03:19 +0000722 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata9fc19442011-07-06 02:13:41 +0000723 *percent_position = ::strchr(var_name_begin,'%');
Greg Clayton34132752011-07-06 04:07:21 +0000724 if (!*percent_position || *percent_position > var_name_end)
Enrico Granatae992a082011-07-22 17:03:19 +0000725 {
726 if (log)
727 log->Printf("no format descriptor in string, skipping");
Enrico Granata9fc19442011-07-06 02:13:41 +0000728 *var_name_final = var_name_end;
Enrico Granatae992a082011-07-22 17:03:19 +0000729 }
Enrico Granata9fc19442011-07-06 02:13:41 +0000730 else
731 {
732 *var_name_final = *percent_position;
733 char* format_name = new char[var_name_end-*var_name_final]; format_name[var_name_end-*var_name_final-1] = '\0';
734 memcpy(format_name, *var_name_final+1, var_name_end-*var_name_final-1);
Enrico Granatae992a082011-07-22 17:03:19 +0000735 if (log)
736 log->Printf("parsing %s as a format descriptor", format_name);
Enrico Granata9fc19442011-07-06 02:13:41 +0000737 if ( !FormatManager::GetFormatFromCString(format_name,
738 true,
739 *custom_format) )
740 {
Enrico Granatae992a082011-07-22 17:03:19 +0000741 if (log)
742 log->Printf("%s is an unknown format", format_name);
Enrico Granata9fc19442011-07-06 02:13:41 +0000743 // if this is an @ sign, print ObjC description
Greg Clayton34132752011-07-06 04:07:21 +0000744 if (*format_name == '@')
Enrico Granata9fc19442011-07-06 02:13:41 +0000745 *val_obj_display = ValueObject::eDisplayLanguageSpecific;
746 // if this is a V, print the value using the default format
Enrico Granatae992a082011-07-22 17:03:19 +0000747 else if (*format_name == 'V')
Enrico Granata9fc19442011-07-06 02:13:41 +0000748 *val_obj_display = ValueObject::eDisplayValue;
Enrico Granatad55546b2011-07-22 00:16:08 +0000749 // if this is an L, print the location of the value
Enrico Granatae992a082011-07-22 17:03:19 +0000750 else if (*format_name == 'L')
Enrico Granataf2bbf712011-07-15 02:26:42 +0000751 *val_obj_display = ValueObject::eDisplayLocation;
Enrico Granatad55546b2011-07-22 00:16:08 +0000752 // if this is an S, print the summary after all
Enrico Granatae992a082011-07-22 17:03:19 +0000753 else if (*format_name == 'S')
Enrico Granatad55546b2011-07-22 00:16:08 +0000754 *val_obj_display = ValueObject::eDisplaySummary;
Enrico Granata5dfd49c2011-08-04 02:34:29 +0000755 else if (*format_name == '#')
756 *val_obj_display = ValueObject::eDisplayChildrenCount;
Enrico Granatad64d0bc2011-08-19 21:13:46 +0000757 else if (*format_name == 'T')
758 *val_obj_display = ValueObject::eDisplayType;
Enrico Granatae992a082011-07-22 17:03:19 +0000759 else if (log)
760 log->Printf("%s is an error, leaving the previous value alone", format_name);
Enrico Granata9fc19442011-07-06 02:13:41 +0000761 }
762 // a good custom format tells us to print the value using it
763 else
Enrico Granatae992a082011-07-22 17:03:19 +0000764 {
765 if (log)
766 log->Printf("will display value for this VO");
Enrico Granata9fc19442011-07-06 02:13:41 +0000767 *val_obj_display = ValueObject::eDisplayValue;
Enrico Granatae992a082011-07-22 17:03:19 +0000768 }
Enrico Granata9fc19442011-07-06 02:13:41 +0000769 delete format_name;
770 }
Enrico Granatae992a082011-07-22 17:03:19 +0000771 if (log)
772 log->Printf("final format description outcome: custom_format = %d, val_obj_display = %d",
773 *custom_format,
774 *val_obj_display);
Enrico Granata9fc19442011-07-06 02:13:41 +0000775 return true;
776}
777
778static bool
Enrico Granatadc940732011-08-23 00:32:52 +0000779ScanBracketedRange (const char* var_name_begin,
780 const char* var_name_end,
781 const char* var_name_final,
782 const char** open_bracket_position,
783 const char** separator_position,
784 const char** close_bracket_position,
785 const char** var_name_final_if_array_range,
786 int64_t* index_lower,
787 int64_t* index_higher)
Enrico Granata9fc19442011-07-06 02:13:41 +0000788{
Enrico Granatae992a082011-07-22 17:03:19 +0000789 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata9fc19442011-07-06 02:13:41 +0000790 *open_bracket_position = ::strchr(var_name_begin,'[');
Greg Clayton34132752011-07-06 04:07:21 +0000791 if (*open_bracket_position && *open_bracket_position < var_name_final)
Enrico Granata9fc19442011-07-06 02:13:41 +0000792 {
793 *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
794 *close_bracket_position = ::strchr(*open_bracket_position,']');
795 // as usual, we assume that [] will come before %
796 //printf("trying to expand a []\n");
797 *var_name_final_if_array_range = *open_bracket_position;
Greg Clayton34132752011-07-06 04:07:21 +0000798 if (*close_bracket_position - *open_bracket_position == 1)
Enrico Granata9fc19442011-07-06 02:13:41 +0000799 {
Enrico Granatae992a082011-07-22 17:03:19 +0000800 if (log)
801 log->Printf("[] detected.. going from 0 to end of data");
Enrico Granata9fc19442011-07-06 02:13:41 +0000802 *index_lower = 0;
803 }
804 else if (*separator_position == NULL || *separator_position > var_name_end)
805 {
806 char *end = NULL;
807 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
808 *index_higher = *index_lower;
Enrico Granatae992a082011-07-22 17:03:19 +0000809 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000810 log->Printf("[%lld] detected, high index is same", *index_lower);
Enrico Granata9fc19442011-07-06 02:13:41 +0000811 }
Greg Clayton34132752011-07-06 04:07:21 +0000812 else if (*close_bracket_position && *close_bracket_position < var_name_end)
Enrico Granata9fc19442011-07-06 02:13:41 +0000813 {
814 char *end = NULL;
815 *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
816 *index_higher = ::strtoul (*separator_position+1, &end, 0);
Enrico Granatae992a082011-07-22 17:03:19 +0000817 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000818 log->Printf("[%lld-%lld] detected", *index_lower, *index_higher);
Enrico Granata9fc19442011-07-06 02:13:41 +0000819 }
820 else
Enrico Granatae992a082011-07-22 17:03:19 +0000821 {
822 if (log)
823 log->Printf("expression is erroneous, cannot extract indices out of it");
Enrico Granata9fc19442011-07-06 02:13:41 +0000824 return false;
Enrico Granatae992a082011-07-22 17:03:19 +0000825 }
Enrico Granata9fc19442011-07-06 02:13:41 +0000826 if (*index_lower > *index_higher && *index_higher > 0)
827 {
Enrico Granatae992a082011-07-22 17:03:19 +0000828 if (log)
829 log->Printf("swapping indices");
Enrico Granata9fc19442011-07-06 02:13:41 +0000830 int temp = *index_lower;
831 *index_lower = *index_higher;
832 *index_higher = temp;
833 }
834 }
Enrico Granatae992a082011-07-22 17:03:19 +0000835 else if (log)
836 log->Printf("no bracketed range, skipping entirely");
Enrico Granata9fc19442011-07-06 02:13:41 +0000837 return true;
838}
839
840
841static ValueObjectSP
Enrico Granatadc940732011-08-23 00:32:52 +0000842ExpandExpressionPath (ValueObject* valobj,
843 StackFrame* frame,
844 bool* do_deref_pointer,
845 const char* var_name_begin,
846 const char* var_name_final,
847 Error& error)
Enrico Granata9fc19442011-07-06 02:13:41 +0000848{
Enrico Granatae992a082011-07-22 17:03:19 +0000849 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granata9fc19442011-07-06 02:13:41 +0000850 StreamString sstring;
851 VariableSP var_sp;
852
Greg Clayton34132752011-07-06 04:07:21 +0000853 if (*do_deref_pointer)
Enrico Granatae992a082011-07-22 17:03:19 +0000854 {
855 if (log)
856 log->Printf("been told to deref_pointer by caller");
Enrico Granata9fc19442011-07-06 02:13:41 +0000857 sstring.PutChar('*');
Enrico Granatae992a082011-07-22 17:03:19 +0000858 }
Enrico Granatac482a192011-08-17 22:13:59 +0000859 else if (valobj->IsDereferenceOfParent() && ClangASTContext::IsPointerType(valobj->GetParent()->GetClangType()) && !valobj->IsArrayItemForPointer())
Enrico Granata9fc19442011-07-06 02:13:41 +0000860 {
Enrico Granatae992a082011-07-22 17:03:19 +0000861 if (log)
862 log->Printf("decided to deref_pointer myself");
Enrico Granata9fc19442011-07-06 02:13:41 +0000863 sstring.PutChar('*');
864 *do_deref_pointer = true;
865 }
866
Enrico Granatac482a192011-08-17 22:13:59 +0000867 valobj->GetExpressionPath(sstring, true, ValueObject::eHonorPointers);
Enrico Granatae992a082011-07-22 17:03:19 +0000868 if (log)
869 log->Printf("expression path to expand in phase 0: %s",sstring.GetData());
Enrico Granata9fc19442011-07-06 02:13:41 +0000870 sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3);
Enrico Granatae992a082011-07-22 17:03:19 +0000871 if (log)
872 log->Printf("expression path to expand in phase 1: %s",sstring.GetData());
Enrico Granata9fc19442011-07-06 02:13:41 +0000873 std::string name = std::string(sstring.GetData());
874 ValueObjectSP target = frame->GetValueForVariableExpressionPath (name.c_str(),
875 eNoDynamicValues,
876 0,
877 var_sp,
878 error);
879 return target;
880}
881
882static ValueObjectSP
Enrico Granatadc940732011-08-23 00:32:52 +0000883ExpandIndexedExpression (ValueObject* valobj,
884 uint32_t index,
885 StackFrame* frame,
886 bool deref_pointer)
Enrico Granata9fc19442011-07-06 02:13:41 +0000887{
Enrico Granatae992a082011-07-22 17:03:19 +0000888 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Enrico Granatafc7a7f32011-07-08 02:51:01 +0000889 const char* ptr_deref_format = "[%d]";
890 std::auto_ptr<char> ptr_deref_buffer(new char[10]);
891 ::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index);
Enrico Granatae992a082011-07-22 17:03:19 +0000892 if (log)
893 log->Printf("name to deref: %s",ptr_deref_buffer.get());
Enrico Granatafc7a7f32011-07-08 02:51:01 +0000894 const char* first_unparsed;
895 ValueObject::GetValueForExpressionPathOptions options;
896 ValueObject::ExpressionPathEndResultType final_value_type;
897 ValueObject::ExpressionPathScanEndReason reason_to_stop;
898 ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eDereference : ValueObject::eNothing);
Enrico Granatac482a192011-08-17 22:13:59 +0000899 ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.get(),
Enrico Granatafc7a7f32011-07-08 02:51:01 +0000900 &first_unparsed,
901 &reason_to_stop,
902 &final_value_type,
903 options,
904 &what_next);
905 if (!item)
906 {
Enrico Granatae992a082011-07-22 17:03:19 +0000907 if (log)
908 log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
909 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +0000910 first_unparsed, reason_to_stop, final_value_type);
Enrico Granatafc7a7f32011-07-08 02:51:01 +0000911 }
Enrico Granata9fc19442011-07-06 02:13:41 +0000912 else
913 {
Enrico Granatae992a082011-07-22 17:03:19 +0000914 if (log)
915 log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
916 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +0000917 first_unparsed, reason_to_stop, final_value_type);
Enrico Granata9fc19442011-07-06 02:13:41 +0000918 }
919 return item;
920}
921
Greg Clayton1b654882010-09-19 02:33:57 +0000922bool
923Debugger::FormatPrompt
924(
925 const char *format,
926 const SymbolContext *sc,
927 const ExecutionContext *exe_ctx,
928 const Address *addr,
929 Stream &s,
Enrico Granata4becb372011-06-29 22:27:15 +0000930 const char **end,
Enrico Granatac482a192011-08-17 22:13:59 +0000931 ValueObject* valobj
Greg Clayton1b654882010-09-19 02:33:57 +0000932)
933{
Enrico Granatac482a192011-08-17 22:13:59 +0000934 ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
Greg Clayton1b654882010-09-19 02:33:57 +0000935 bool success = true;
936 const char *p;
Enrico Granatae992a082011-07-22 17:03:19 +0000937 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Greg Clayton1b654882010-09-19 02:33:57 +0000938 for (p = format; *p != '\0'; ++p)
939 {
Enrico Granatac482a192011-08-17 22:13:59 +0000940 if (realvalobj)
Enrico Granata4becb372011-06-29 22:27:15 +0000941 {
Enrico Granatac482a192011-08-17 22:13:59 +0000942 valobj = realvalobj;
943 realvalobj = NULL;
Enrico Granata4becb372011-06-29 22:27:15 +0000944 }
Greg Clayton1b654882010-09-19 02:33:57 +0000945 size_t non_special_chars = ::strcspn (p, "${}\\");
946 if (non_special_chars > 0)
947 {
948 if (success)
949 s.Write (p, non_special_chars);
950 p += non_special_chars;
951 }
952
953 if (*p == '\0')
954 {
955 break;
956 }
957 else if (*p == '{')
958 {
959 // Start a new scope that must have everything it needs if it is to
960 // to make it into the final output stream "s". If you want to make
961 // a format that only prints out the function or symbol name if there
962 // is one in the symbol context you can use:
963 // "{function =${function.name}}"
964 // The first '{' starts a new scope that end with the matching '}' at
965 // the end of the string. The contents "function =${function.name}"
966 // will then be evaluated and only be output if there is a function
967 // or symbol with a valid name.
968 StreamString sub_strm;
969
970 ++p; // Skip the '{'
971
Enrico Granatac482a192011-08-17 22:13:59 +0000972 if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, valobj))
Greg Clayton1b654882010-09-19 02:33:57 +0000973 {
974 // The stream had all it needed
975 s.Write(sub_strm.GetData(), sub_strm.GetSize());
976 }
977 if (*p != '}')
978 {
979 success = false;
980 break;
981 }
982 }
983 else if (*p == '}')
984 {
985 // End of a enclosing scope
986 break;
987 }
988 else if (*p == '$')
989 {
990 // We have a prompt variable to print
991 ++p;
992 if (*p == '{')
993 {
994 ++p;
995 const char *var_name_begin = p;
996 const char *var_name_end = ::strchr (p, '}');
997
998 if (var_name_end && var_name_begin < var_name_end)
999 {
1000 // if we have already failed to parse, skip this variable
1001 if (success)
1002 {
1003 const char *cstr = NULL;
1004 Address format_addr;
1005 bool calculate_format_addr_function_offset = false;
1006 // Set reg_kind and reg_num to invalid values
1007 RegisterKind reg_kind = kNumRegisterKinds;
1008 uint32_t reg_num = LLDB_INVALID_REGNUM;
1009 FileSpec format_file_spec;
Greg Claytone0d378b2011-03-24 21:19:54 +00001010 const RegisterInfo *reg_info = NULL;
Greg Clayton1b654882010-09-19 02:33:57 +00001011 RegisterContext *reg_ctx = NULL;
Enrico Granata9fc19442011-07-06 02:13:41 +00001012 bool do_deref_pointer = false;
Enrico Granatae992a082011-07-22 17:03:19 +00001013 ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eEndOfString;
1014 ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::ePlain;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001015
Greg Clayton1b654882010-09-19 02:33:57 +00001016 // Each variable must set success to true below...
1017 bool var_success = false;
1018 switch (var_name_begin[0])
1019 {
Enrico Granata4becb372011-06-29 22:27:15 +00001020 case '*':
Enrico Granata4becb372011-06-29 22:27:15 +00001021 case 'v':
Enrico Granata6f3533f2011-07-29 19:53:35 +00001022 case 's':
Enrico Granata4becb372011-06-29 22:27:15 +00001023 {
Enrico Granatac482a192011-08-17 22:13:59 +00001024 if (!valobj)
Enrico Granata6f3533f2011-07-29 19:53:35 +00001025 break;
1026
Enrico Granatac3e320a2011-08-02 17:27:39 +00001027 if (log)
1028 log->Printf("initial string: %s",var_name_begin);
1029
Enrico Granata6f3533f2011-07-29 19:53:35 +00001030 // check for *var and *svar
1031 if (*var_name_begin == '*')
1032 {
1033 do_deref_pointer = true;
1034 var_name_begin++;
1035 }
Enrico Granatac3e320a2011-08-02 17:27:39 +00001036
1037 if (log)
1038 log->Printf("initial string: %s",var_name_begin);
1039
Enrico Granata6f3533f2011-07-29 19:53:35 +00001040 if (*var_name_begin == 's')
1041 {
Greg Clayton4d122c42011-09-17 08:33:22 +00001042 valobj = valobj->GetSyntheticValue(eUseSyntheticFilter).get();
Enrico Granata6f3533f2011-07-29 19:53:35 +00001043 var_name_begin++;
1044 }
1045
Enrico Granatac3e320a2011-08-02 17:27:39 +00001046 if (log)
1047 log->Printf("initial string: %s",var_name_begin);
1048
Enrico Granata6f3533f2011-07-29 19:53:35 +00001049 // should be a 'v' by now
1050 if (*var_name_begin != 'v')
1051 break;
1052
Enrico Granatac3e320a2011-08-02 17:27:39 +00001053 if (log)
1054 log->Printf("initial string: %s",var_name_begin);
1055
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001056 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
1057 ValueObject::eDereference : ValueObject::eNothing);
1058 ValueObject::GetValueForExpressionPathOptions options;
Enrico Granata8c9d3562011-08-11 17:08:01 +00001059 options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
Greg Clayton34132752011-07-06 04:07:21 +00001060 ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary;
1061 ValueObject* target = NULL;
Greg Clayton4d122c42011-09-17 08:33:22 +00001062 Format custom_format = eFormatInvalid;
Greg Clayton34132752011-07-06 04:07:21 +00001063 const char* var_name_final = NULL;
1064 const char* var_name_final_if_array_range = NULL;
1065 const char* close_bracket_position = NULL;
1066 int64_t index_lower = -1;
1067 int64_t index_higher = -1;
1068 bool is_array_range = false;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001069 const char* first_unparsed;
Enrico Granata85933ed2011-08-18 16:38:26 +00001070 bool was_plain_var = false;
1071 bool was_var_format = false;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001072
Enrico Granatac482a192011-08-17 22:13:59 +00001073 if (!valobj) break;
1074 // simplest case ${var}, just print valobj's value
Greg Clayton34132752011-07-06 04:07:21 +00001075 if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0)
Enrico Granata4becb372011-06-29 22:27:15 +00001076 {
Enrico Granata85933ed2011-08-18 16:38:26 +00001077 was_plain_var = true;
Enrico Granatac482a192011-08-17 22:13:59 +00001078 target = valobj;
Greg Clayton34132752011-07-06 04:07:21 +00001079 val_obj_display = ValueObject::eDisplayValue;
1080 }
1081 else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0)
1082 {
Enrico Granata85933ed2011-08-18 16:38:26 +00001083 was_var_format = true;
Greg Clayton34132752011-07-06 04:07:21 +00001084 // this is a variable with some custom format applied to it
1085 const char* percent_position;
Enrico Granatac482a192011-08-17 22:13:59 +00001086 target = valobj;
Greg Clayton34132752011-07-06 04:07:21 +00001087 val_obj_display = ValueObject::eDisplayValue;
1088 ScanFormatDescriptor (var_name_begin,
1089 var_name_end,
1090 &var_name_final,
1091 &percent_position,
1092 &custom_format,
1093 &val_obj_display);
1094 }
1095 // this is ${var.something} or multiple .something nested
1096 else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
1097 {
1098
1099 const char* percent_position;
1100 ScanFormatDescriptor (var_name_begin,
1101 var_name_end,
1102 &var_name_final,
1103 &percent_position,
1104 &custom_format,
1105 &val_obj_display);
1106
1107 const char* open_bracket_position;
1108 const char* separator_position;
1109 ScanBracketedRange (var_name_begin,
1110 var_name_end,
1111 var_name_final,
1112 &open_bracket_position,
1113 &separator_position,
1114 &close_bracket_position,
1115 &var_name_final_if_array_range,
1116 &index_lower,
1117 &index_higher);
1118
1119 Error error;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001120
1121 std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]);
1122 ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
1123 memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
1124
Enrico Granatae992a082011-07-22 17:03:19 +00001125 if (log)
1126 log->Printf("symbol to expand: %s",expr_path.get());
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001127
Enrico Granatac482a192011-08-17 22:13:59 +00001128 target = valobj->GetValueForExpressionPath(expr_path.get(),
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001129 &first_unparsed,
1130 &reason_to_stop,
1131 &final_value_type,
1132 options,
1133 &what_next).get();
1134
1135 if (!target)
Enrico Granata9fc19442011-07-06 02:13:41 +00001136 {
Enrico Granatae992a082011-07-22 17:03:19 +00001137 if (log)
1138 log->Printf("ERROR: unparsed portion = %s, why stopping = %d,"
1139 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001140 first_unparsed, reason_to_stop, final_value_type);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001141 break;
Enrico Granata9fc19442011-07-06 02:13:41 +00001142 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001143 else
1144 {
Enrico Granatae992a082011-07-22 17:03:19 +00001145 if (log)
1146 log->Printf("ALL RIGHT: unparsed portion = %s, why stopping = %d,"
1147 " final_value_type %d",
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001148 first_unparsed, reason_to_stop, final_value_type);
1149 }
Enrico Granata4becb372011-06-29 22:27:15 +00001150 }
Greg Clayton34132752011-07-06 04:07:21 +00001151 else
Enrico Granata9fc19442011-07-06 02:13:41 +00001152 break;
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001153
1154 is_array_range = (final_value_type == ValueObject::eBoundedRange ||
1155 final_value_type == ValueObject::eUnboundedRange);
1156
1157 do_deref_pointer = (what_next == ValueObject::eDereference);
Enrico Granata9fc19442011-07-06 02:13:41 +00001158
Enrico Granataa7187d02011-07-06 19:27:11 +00001159 if (do_deref_pointer && !is_array_range)
Enrico Granata9fc19442011-07-06 02:13:41 +00001160 {
Greg Clayton34132752011-07-06 04:07:21 +00001161 // I have not deref-ed yet, let's do it
1162 // this happens when we are not going through GetValueForVariableExpressionPath
1163 // to get to the target ValueObject
Enrico Granata9fc19442011-07-06 02:13:41 +00001164 Error error;
Greg Clayton34132752011-07-06 04:07:21 +00001165 target = target->Dereference(error).get();
Enrico Granatadc940732011-08-23 00:32:52 +00001166 if (error.Fail())
1167 {
1168 if (log)
1169 log->Printf("ERROR: %s\n", error.AsCString("unknown")); \
1170 break;
1171 }
Greg Clayton34132752011-07-06 04:07:21 +00001172 do_deref_pointer = false;
Enrico Granata9fc19442011-07-06 02:13:41 +00001173 }
Enrico Granataf4efecd2011-07-12 22:56:10 +00001174
Enrico Granata85933ed2011-08-18 16:38:26 +00001175 // TODO use flags for these
Enrico Granataf4efecd2011-07-12 22:56:10 +00001176 bool is_array = ClangASTContext::IsArrayType(target->GetClangType());
1177 bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
Enrico Granata85933ed2011-08-18 16:38:26 +00001178 bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
Enrico Granataf4efecd2011-07-12 22:56:10 +00001179
1180 if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eDisplayValue) // this should be wrong, but there are some exceptions
1181 {
Enrico Granata85933ed2011-08-18 16:38:26 +00001182 StreamString str_temp;
Enrico Granatae992a082011-07-22 17:03:19 +00001183 if (log)
1184 log->Printf("I am into array || pointer && !range");
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001185
1186 if (target->HasSpecialCasesForPrintableRepresentation(val_obj_display,
1187 custom_format))
Enrico Granata85933ed2011-08-18 16:38:26 +00001188 {
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001189 // try to use the special cases
1190 var_success = target->DumpPrintableRepresentation(str_temp,
1191 val_obj_display,
1192 custom_format);
1193 if (log)
1194 log->Printf("special cases did%s match", var_success ? "" : "n't");
1195
1196 // should not happen
1197 if (!var_success)
1198 s << "<invalid usage of pointer value as object>";
1199 else
1200 s << str_temp.GetData();
Enrico Granata85933ed2011-08-18 16:38:26 +00001201 var_success = true;
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001202 break;
Enrico Granata85933ed2011-08-18 16:38:26 +00001203 }
1204 else
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001205 {
Enrico Granata88da35f2011-08-23 21:26:09 +00001206 if (was_plain_var) // if ${var}
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001207 {
1208 s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1209 }
Enrico Granata88da35f2011-08-23 21:26:09 +00001210 else if (is_pointer) // if pointer, value is the address stored
1211 {
1212 var_success = target->GetPrintableRepresentation(s,
1213 val_obj_display,
1214 custom_format);
1215 }
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001216 else
1217 {
1218 s << "<invalid usage of pointer value as object>";
1219 }
1220 var_success = true;
1221 break;
1222 }
1223 }
1224
1225 // if directly trying to print ${var}, and this is an aggregate, display a nice
1226 // type @ location message
1227 if (is_aggregate && was_plain_var)
1228 {
1229 s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
1230 var_success = true;
Enrico Granata85933ed2011-08-18 16:38:26 +00001231 break;
1232 }
1233
Enrico Granatad64d0bc2011-08-19 21:13:46 +00001234 // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
1235 if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eDisplayValue)))
Enrico Granata85933ed2011-08-18 16:38:26 +00001236 {
1237 s << "<invalid use of aggregate type>";
1238 var_success = true;
Enrico Granataf4efecd2011-07-12 22:56:10 +00001239 break;
1240 }
Greg Clayton34132752011-07-06 04:07:21 +00001241
1242 if (!is_array_range)
Enrico Granatae992a082011-07-22 17:03:19 +00001243 {
1244 if (log)
1245 log->Printf("dumping ordinary printable output");
Greg Clayton34132752011-07-06 04:07:21 +00001246 var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
Enrico Granatae992a082011-07-22 17:03:19 +00001247 }
Greg Clayton34132752011-07-06 04:07:21 +00001248 else
Enrico Granatae992a082011-07-22 17:03:19 +00001249 {
1250 if (log)
1251 log->Printf("checking if I can handle as array");
Greg Clayton34132752011-07-06 04:07:21 +00001252 if (!is_array && !is_pointer)
1253 break;
Enrico Granatae992a082011-07-22 17:03:19 +00001254 if (log)
1255 log->Printf("handle as array");
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001256 const char* special_directions = NULL;
1257 StreamString special_directions_writer;
Greg Clayton34132752011-07-06 04:07:21 +00001258 if (close_bracket_position && (var_name_end-close_bracket_position > 1))
1259 {
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001260 ConstString additional_data;
1261 additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
1262 special_directions_writer.Printf("${%svar%s}",
1263 do_deref_pointer ? "*" : "",
1264 additional_data.GetCString());
1265 special_directions = special_directions_writer.GetData();
Greg Clayton34132752011-07-06 04:07:21 +00001266 }
1267
1268 // let us display items index_lower thru index_higher of this array
1269 s.PutChar('[');
1270 var_success = true;
1271
1272 if (index_higher < 0)
Enrico Granatac482a192011-08-17 22:13:59 +00001273 index_higher = valobj->GetNumChildren() - 1;
Greg Clayton34132752011-07-06 04:07:21 +00001274
Enrico Granata22c55d12011-08-12 02:00:06 +00001275 uint32_t max_num_children = target->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1276
Greg Clayton34132752011-07-06 04:07:21 +00001277 for (;index_lower<=index_higher;index_lower++)
1278 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001279 ValueObject* item = ExpandIndexedExpression (target,
1280 index_lower,
1281 exe_ctx->GetFramePtr(),
1282 false).get();
Greg Clayton34132752011-07-06 04:07:21 +00001283
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001284 if (!item)
1285 {
Enrico Granatae992a082011-07-22 17:03:19 +00001286 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +00001287 log->Printf("ERROR in getting child item at index %lld", index_lower);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001288 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001289 else
1290 {
Enrico Granatae992a082011-07-22 17:03:19 +00001291 if (log)
1292 log->Printf("special_directions for child item: %s",special_directions);
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001293 }
Enrico Granatafc7a7f32011-07-08 02:51:01 +00001294
Greg Clayton34132752011-07-06 04:07:21 +00001295 if (!special_directions)
1296 var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
1297 else
1298 var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
1299
Enrico Granata22c55d12011-08-12 02:00:06 +00001300 if (--max_num_children == 0)
1301 {
1302 s.PutCString(", ...");
1303 break;
1304 }
1305
Greg Clayton34132752011-07-06 04:07:21 +00001306 if (index_lower < index_higher)
1307 s.PutChar(',');
1308 }
1309 s.PutChar(']');
1310 }
Enrico Granata4becb372011-06-29 22:27:15 +00001311 }
Enrico Granata9fc19442011-07-06 02:13:41 +00001312 break;
Greg Clayton1b654882010-09-19 02:33:57 +00001313 case 'a':
1314 if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
1315 {
1316 if (addr && addr->IsValid())
1317 {
1318 var_success = true;
1319 format_addr = *addr;
1320 }
1321 }
Greg Clayton5a314712011-10-14 07:41:33 +00001322 else if (::strncmp (var_name_begin, "ansi.", strlen("ansi.")) == 0)
1323 {
1324 var_success = true;
1325 var_name_begin += strlen("ansi."); // Skip the "ansi."
1326 if (::strncmp (var_name_begin, "fg.", strlen("fg.")) == 0)
1327 {
1328 var_name_begin += strlen("fg."); // Skip the "fg."
1329 if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1330 {
1331 s.Printf ("%s%s%s",
1332 lldb_utility::ansi::k_escape_start,
1333 lldb_utility::ansi::k_fg_black,
1334 lldb_utility::ansi::k_escape_end);
1335 }
1336 else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1337 {
1338 s.Printf ("%s%s%s",
1339 lldb_utility::ansi::k_escape_start,
1340 lldb_utility::ansi::k_fg_red,
1341 lldb_utility::ansi::k_escape_end);
1342 }
1343 else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1344 {
1345 s.Printf ("%s%s%s",
1346 lldb_utility::ansi::k_escape_start,
1347 lldb_utility::ansi::k_fg_green,
1348 lldb_utility::ansi::k_escape_end);
1349 }
1350 else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1351 {
1352 s.Printf ("%s%s%s",
1353 lldb_utility::ansi::k_escape_start,
1354 lldb_utility::ansi::k_fg_yellow,
1355 lldb_utility::ansi::k_escape_end);
1356 }
1357 else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1358 {
1359 s.Printf ("%s%s%s",
1360 lldb_utility::ansi::k_escape_start,
1361 lldb_utility::ansi::k_fg_blue,
1362 lldb_utility::ansi::k_escape_end);
1363 }
1364 else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1365 {
1366 s.Printf ("%s%s%s",
1367 lldb_utility::ansi::k_escape_start,
1368 lldb_utility::ansi::k_fg_purple,
1369 lldb_utility::ansi::k_escape_end);
1370 }
1371 else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1372 {
1373 s.Printf ("%s%s%s",
1374 lldb_utility::ansi::k_escape_start,
1375 lldb_utility::ansi::k_fg_cyan,
1376 lldb_utility::ansi::k_escape_end);
1377 }
1378 else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1379 {
1380 s.Printf ("%s%s%s",
1381 lldb_utility::ansi::k_escape_start,
1382 lldb_utility::ansi::k_fg_white,
1383 lldb_utility::ansi::k_escape_end);
1384 }
1385 else
1386 {
1387 var_success = false;
1388 }
1389 }
1390 else if (::strncmp (var_name_begin, "bg.", strlen("bg.")) == 0)
1391 {
1392 var_name_begin += strlen("bg."); // Skip the "bg."
1393 if (::strncmp (var_name_begin, "black}", strlen("black}")) == 0)
1394 {
1395 s.Printf ("%s%s%s",
1396 lldb_utility::ansi::k_escape_start,
1397 lldb_utility::ansi::k_bg_black,
1398 lldb_utility::ansi::k_escape_end);
1399 }
1400 else if (::strncmp (var_name_begin, "red}", strlen("red}")) == 0)
1401 {
1402 s.Printf ("%s%s%s",
1403 lldb_utility::ansi::k_escape_start,
1404 lldb_utility::ansi::k_bg_red,
1405 lldb_utility::ansi::k_escape_end);
1406 }
1407 else if (::strncmp (var_name_begin, "green}", strlen("green}")) == 0)
1408 {
1409 s.Printf ("%s%s%s",
1410 lldb_utility::ansi::k_escape_start,
1411 lldb_utility::ansi::k_bg_green,
1412 lldb_utility::ansi::k_escape_end);
1413 }
1414 else if (::strncmp (var_name_begin, "yellow}", strlen("yellow}")) == 0)
1415 {
1416 s.Printf ("%s%s%s",
1417 lldb_utility::ansi::k_escape_start,
1418 lldb_utility::ansi::k_bg_yellow,
1419 lldb_utility::ansi::k_escape_end);
1420 }
1421 else if (::strncmp (var_name_begin, "blue}", strlen("blue}")) == 0)
1422 {
1423 s.Printf ("%s%s%s",
1424 lldb_utility::ansi::k_escape_start,
1425 lldb_utility::ansi::k_bg_blue,
1426 lldb_utility::ansi::k_escape_end);
1427 }
1428 else if (::strncmp (var_name_begin, "purple}", strlen("purple}")) == 0)
1429 {
1430 s.Printf ("%s%s%s",
1431 lldb_utility::ansi::k_escape_start,
1432 lldb_utility::ansi::k_bg_purple,
1433 lldb_utility::ansi::k_escape_end);
1434 }
1435 else if (::strncmp (var_name_begin, "cyan}", strlen("cyan}")) == 0)
1436 {
1437 s.Printf ("%s%s%s",
1438 lldb_utility::ansi::k_escape_start,
1439 lldb_utility::ansi::k_bg_cyan,
1440 lldb_utility::ansi::k_escape_end);
1441 }
1442 else if (::strncmp (var_name_begin, "white}", strlen("white}")) == 0)
1443 {
1444 s.Printf ("%s%s%s",
1445 lldb_utility::ansi::k_escape_start,
1446 lldb_utility::ansi::k_bg_white,
1447 lldb_utility::ansi::k_escape_end);
1448 }
1449 else
1450 {
1451 var_success = false;
1452 }
1453 }
1454 else if (::strncmp (var_name_begin, "normal}", strlen ("normal}")) == 0)
1455 {
1456 s.Printf ("%s%s%s",
1457 lldb_utility::ansi::k_escape_start,
1458 lldb_utility::ansi::k_ctrl_normal,
1459 lldb_utility::ansi::k_escape_end);
1460 }
1461 else if (::strncmp (var_name_begin, "bold}", strlen("bold}")) == 0)
1462 {
1463 s.Printf ("%s%s%s",
1464 lldb_utility::ansi::k_escape_start,
1465 lldb_utility::ansi::k_ctrl_bold,
1466 lldb_utility::ansi::k_escape_end);
1467 }
1468 else if (::strncmp (var_name_begin, "faint}", strlen("faint}")) == 0)
1469 {
1470 s.Printf ("%s%s%s",
1471 lldb_utility::ansi::k_escape_start,
1472 lldb_utility::ansi::k_ctrl_faint,
1473 lldb_utility::ansi::k_escape_end);
1474 }
1475 else if (::strncmp (var_name_begin, "italic}", strlen("italic}")) == 0)
1476 {
1477 s.Printf ("%s%s%s",
1478 lldb_utility::ansi::k_escape_start,
1479 lldb_utility::ansi::k_ctrl_italic,
1480 lldb_utility::ansi::k_escape_end);
1481 }
1482 else if (::strncmp (var_name_begin, "underline}", strlen("underline}")) == 0)
1483 {
1484 s.Printf ("%s%s%s",
1485 lldb_utility::ansi::k_escape_start,
1486 lldb_utility::ansi::k_ctrl_underline,
1487 lldb_utility::ansi::k_escape_end);
1488 }
1489 else if (::strncmp (var_name_begin, "slow-blink}", strlen("slow-blink}")) == 0)
1490 {
1491 s.Printf ("%s%s%s",
1492 lldb_utility::ansi::k_escape_start,
1493 lldb_utility::ansi::k_ctrl_slow_blink,
1494 lldb_utility::ansi::k_escape_end);
1495 }
1496 else if (::strncmp (var_name_begin, "fast-blink}", strlen("fast-blink}")) == 0)
1497 {
1498 s.Printf ("%s%s%s",
1499 lldb_utility::ansi::k_escape_start,
1500 lldb_utility::ansi::k_ctrl_fast_blink,
1501 lldb_utility::ansi::k_escape_end);
1502 }
1503 else if (::strncmp (var_name_begin, "negative}", strlen("negative}")) == 0)
1504 {
1505 s.Printf ("%s%s%s",
1506 lldb_utility::ansi::k_escape_start,
1507 lldb_utility::ansi::k_ctrl_negative,
1508 lldb_utility::ansi::k_escape_end);
1509 }
1510 else if (::strncmp (var_name_begin, "conceal}", strlen("conceal}")) == 0)
1511 {
1512 s.Printf ("%s%s%s",
1513 lldb_utility::ansi::k_escape_start,
1514 lldb_utility::ansi::k_ctrl_conceal,
1515 lldb_utility::ansi::k_escape_end);
1516
1517 }
1518 else if (::strncmp (var_name_begin, "crossed-out}", strlen("crossed-out}")) == 0)
1519 {
1520 s.Printf ("%s%s%s",
1521 lldb_utility::ansi::k_escape_start,
1522 lldb_utility::ansi::k_ctrl_crossed_out,
1523 lldb_utility::ansi::k_escape_end);
1524 }
1525 else
1526 {
1527 var_success = false;
1528 }
1529 }
Greg Clayton1b654882010-09-19 02:33:57 +00001530 break;
1531
1532 case 'p':
1533 if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
1534 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001535 if (exe_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00001536 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001537 Process *process = exe_ctx->GetProcessPtr();
1538 if (process)
Greg Clayton1b654882010-09-19 02:33:57 +00001539 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001540 var_name_begin += ::strlen ("process.");
1541 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
Greg Clayton1b654882010-09-19 02:33:57 +00001542 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001543 s.Printf("%llu", process->GetID());
Greg Claytonc14ee322011-09-22 04:58:26 +00001544 var_success = true;
1545 }
1546 else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
1547 (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
1548 (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
1549 {
1550 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
1551 if (exe_module)
Greg Clayton1b654882010-09-19 02:33:57 +00001552 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001553 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
1554 {
1555 format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
1556 var_success = format_file_spec;
1557 }
1558 else
1559 {
1560 format_file_spec = exe_module->GetFileSpec();
1561 var_success = format_file_spec;
1562 }
Greg Clayton1b654882010-09-19 02:33:57 +00001563 }
1564 }
1565 }
Greg Claytonc14ee322011-09-22 04:58:26 +00001566 }
Greg Clayton1b654882010-09-19 02:33:57 +00001567 }
1568 break;
1569
1570 case 't':
1571 if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
1572 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001573 if (exe_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00001574 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001575 Thread *thread = exe_ctx->GetThreadPtr();
1576 if (thread)
Greg Clayton1b654882010-09-19 02:33:57 +00001577 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001578 var_name_begin += ::strlen ("thread.");
1579 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
Greg Clayton1b654882010-09-19 02:33:57 +00001580 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001581 s.Printf("0x%4.4llx", thread->GetID());
Greg Claytonc14ee322011-09-22 04:58:26 +00001582 var_success = true;
1583 }
1584 else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
1585 {
1586 s.Printf("%u", thread->GetIndexID());
1587 var_success = true;
1588 }
1589 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1590 {
1591 cstr = thread->GetName();
1592 var_success = cstr && cstr[0];
1593 if (var_success)
Greg Clayton1b654882010-09-19 02:33:57 +00001594 s.PutCString(cstr);
Greg Claytonc14ee322011-09-22 04:58:26 +00001595 }
1596 else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
1597 {
1598 cstr = thread->GetQueueName();
1599 var_success = cstr && cstr[0];
1600 if (var_success)
1601 s.PutCString(cstr);
1602 }
1603 else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
1604 {
1605 StopInfoSP stop_info_sp = thread->GetStopInfo ();
1606 if (stop_info_sp)
1607 {
1608 cstr = stop_info_sp->GetDescription();
1609 if (cstr && cstr[0])
1610 {
1611 s.PutCString(cstr);
1612 var_success = true;
1613 }
Greg Clayton1b654882010-09-19 02:33:57 +00001614 }
1615 }
1616 }
1617 }
1618 }
1619 else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
1620 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001621 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1622 if (target)
Greg Clayton1b654882010-09-19 02:33:57 +00001623 {
Greg Clayton1b654882010-09-19 02:33:57 +00001624 var_name_begin += ::strlen ("target.");
1625 if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
1626 {
1627 ArchSpec arch (target->GetArchitecture ());
1628 if (arch.IsValid())
1629 {
Greg Clayton64195a22011-02-23 00:35:02 +00001630 s.PutCString (arch.GetArchitectureName());
Greg Clayton1b654882010-09-19 02:33:57 +00001631 var_success = true;
1632 }
1633 }
1634 }
1635 }
1636 break;
1637
1638
1639 case 'm':
1640 if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
1641 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001642 if (sc && sc->module_sp.get())
Greg Clayton1b654882010-09-19 02:33:57 +00001643 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001644 Module *module = sc->module_sp.get();
Greg Clayton1b654882010-09-19 02:33:57 +00001645 var_name_begin += ::strlen ("module.");
1646
1647 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1648 {
1649 if (module->GetFileSpec())
1650 {
1651 var_name_begin += ::strlen ("file.");
1652
1653 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1654 {
1655 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
1656 var_success = format_file_spec;
1657 }
1658 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1659 {
1660 format_file_spec = module->GetFileSpec();
1661 var_success = format_file_spec;
1662 }
1663 }
1664 }
1665 }
1666 }
1667 break;
1668
1669
1670 case 'f':
1671 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1672 {
1673 if (sc && sc->comp_unit != NULL)
1674 {
1675 var_name_begin += ::strlen ("file.");
1676
1677 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1678 {
1679 format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
1680 var_success = format_file_spec;
1681 }
1682 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1683 {
1684 format_file_spec = *sc->comp_unit;
1685 var_success = format_file_spec;
1686 }
1687 }
1688 }
1689 else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
1690 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001691 if (exe_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00001692 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001693 StackFrame *frame = exe_ctx->GetFramePtr();
1694 if (frame)
Greg Clayton1b654882010-09-19 02:33:57 +00001695 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001696 var_name_begin += ::strlen ("frame.");
1697 if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
Greg Clayton1b654882010-09-19 02:33:57 +00001698 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001699 s.Printf("%u", frame->GetFrameIndex());
1700 var_success = true;
1701 }
1702 else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
1703 {
1704 reg_kind = eRegisterKindGeneric;
1705 reg_num = LLDB_REGNUM_GENERIC_PC;
1706 var_success = true;
1707 }
1708 else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
1709 {
1710 reg_kind = eRegisterKindGeneric;
1711 reg_num = LLDB_REGNUM_GENERIC_SP;
1712 var_success = true;
1713 }
1714 else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
1715 {
1716 reg_kind = eRegisterKindGeneric;
1717 reg_num = LLDB_REGNUM_GENERIC_FP;
1718 var_success = true;
1719 }
1720 else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
1721 {
1722 reg_kind = eRegisterKindGeneric;
1723 reg_num = LLDB_REGNUM_GENERIC_FLAGS;
1724 var_success = true;
1725 }
1726 else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
1727 {
1728 reg_ctx = frame->GetRegisterContext().get();
1729 if (reg_ctx)
Greg Clayton1b654882010-09-19 02:33:57 +00001730 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001731 var_name_begin += ::strlen ("reg.");
1732 if (var_name_begin < var_name_end)
1733 {
1734 std::string reg_name (var_name_begin, var_name_end);
1735 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
1736 if (reg_info)
1737 var_success = true;
1738 }
Greg Clayton1b654882010-09-19 02:33:57 +00001739 }
1740 }
1741 }
1742 }
1743 }
1744 else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
1745 {
1746 if (sc && (sc->function != NULL || sc->symbol != NULL))
1747 {
1748 var_name_begin += ::strlen ("function.");
1749 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1750 {
1751 if (sc->function)
Greg Clayton81c22f62011-10-19 18:09:39 +00001752 s.Printf("function{0x%8.8llx}", sc->function->GetID());
Greg Clayton1b654882010-09-19 02:33:57 +00001753 else
1754 s.Printf("symbol[%u]", sc->symbol->GetID());
1755
1756 var_success = true;
1757 }
1758 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1759 {
1760 if (sc->function)
1761 cstr = sc->function->GetName().AsCString (NULL);
1762 else if (sc->symbol)
1763 cstr = sc->symbol->GetName().AsCString (NULL);
1764 if (cstr)
1765 {
1766 s.PutCString(cstr);
Greg Clayton0d9c9932010-10-04 17:26:49 +00001767
1768 if (sc->block)
1769 {
1770 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1771 if (inline_block)
1772 {
1773 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
1774 if (inline_info)
1775 {
1776 s.PutCString(" [inlined] ");
1777 inline_info->GetName().Dump(&s);
1778 }
1779 }
1780 }
Greg Clayton1b654882010-09-19 02:33:57 +00001781 var_success = true;
1782 }
1783 }
1784 else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
1785 {
1786 var_success = addr != NULL;
1787 if (var_success)
1788 {
1789 format_addr = *addr;
1790 calculate_format_addr_function_offset = true;
1791 }
1792 }
1793 else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
1794 {
1795 var_success = sc->line_entry.range.GetBaseAddress().IsValid();
1796 if (var_success)
1797 {
1798 format_addr = sc->line_entry.range.GetBaseAddress();
1799 calculate_format_addr_function_offset = true;
1800 }
1801 }
1802 else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
1803 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001804 StackFrame *frame = exe_ctx->GetFramePtr();
1805 var_success = frame != NULL;
Greg Clayton1b654882010-09-19 02:33:57 +00001806 if (var_success)
1807 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001808 format_addr = frame->GetFrameCodeAddress();
Greg Clayton1b654882010-09-19 02:33:57 +00001809 calculate_format_addr_function_offset = true;
1810 }
1811 }
1812 }
1813 }
1814 break;
1815
1816 case 'l':
1817 if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
1818 {
1819 if (sc && sc->line_entry.IsValid())
1820 {
1821 var_name_begin += ::strlen ("line.");
1822 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1823 {
1824 var_name_begin += ::strlen ("file.");
1825
1826 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1827 {
1828 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
1829 var_success = format_file_spec;
1830 }
1831 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1832 {
1833 format_file_spec = sc->line_entry.file;
1834 var_success = format_file_spec;
1835 }
1836 }
1837 else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
1838 {
1839 var_success = true;
1840 s.Printf("%u", sc->line_entry.line);
1841 }
1842 else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
1843 (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
1844 {
1845 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
1846 if (var_success)
1847 {
1848 format_addr = sc->line_entry.range.GetBaseAddress();
1849 if (var_name_begin[0] == 'e')
1850 format_addr.Slide (sc->line_entry.range.GetByteSize());
1851 }
1852 }
1853 }
1854 }
1855 break;
1856 }
1857
1858 if (var_success)
1859 {
1860 // If format addr is valid, then we need to print an address
1861 if (reg_num != LLDB_INVALID_REGNUM)
1862 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001863 StackFrame *frame = exe_ctx->GetFramePtr();
Greg Clayton1b654882010-09-19 02:33:57 +00001864 // We have a register value to display...
1865 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
1866 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001867 format_addr = frame->GetFrameCodeAddress();
Greg Clayton1b654882010-09-19 02:33:57 +00001868 }
1869 else
1870 {
1871 if (reg_ctx == NULL)
Greg Claytonc14ee322011-09-22 04:58:26 +00001872 reg_ctx = frame->GetRegisterContext().get();
Greg Clayton1b654882010-09-19 02:33:57 +00001873
1874 if (reg_ctx)
1875 {
1876 if (reg_kind != kNumRegisterKinds)
1877 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
1878 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
1879 var_success = reg_info != NULL;
1880 }
1881 }
1882 }
1883
1884 if (reg_info != NULL)
1885 {
Greg Clayton7349bd92011-05-09 20:18:18 +00001886 RegisterValue reg_value;
1887 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
1888 if (var_success)
Greg Clayton1b654882010-09-19 02:33:57 +00001889 {
Greg Clayton9a8fa912011-05-15 04:12:07 +00001890 reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
Greg Clayton1b654882010-09-19 02:33:57 +00001891 }
1892 }
1893
1894 if (format_file_spec)
1895 {
1896 s << format_file_spec;
1897 }
1898
1899 // If format addr is valid, then we need to print an address
1900 if (format_addr.IsValid())
1901 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001902 var_success = false;
1903
Greg Clayton1b654882010-09-19 02:33:57 +00001904 if (calculate_format_addr_function_offset)
1905 {
1906 Address func_addr;
Greg Clayton1b654882010-09-19 02:33:57 +00001907
Greg Clayton0603aa92010-10-04 01:05:56 +00001908 if (sc)
1909 {
1910 if (sc->function)
Greg Clayton0d9c9932010-10-04 17:26:49 +00001911 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001912 func_addr = sc->function->GetAddressRange().GetBaseAddress();
Greg Clayton0d9c9932010-10-04 17:26:49 +00001913 if (sc->block)
1914 {
1915 // Check to make sure we aren't in an inline
1916 // function. If we are, use the inline block
1917 // range that contains "format_addr" since
1918 // blocks can be discontiguous.
1919 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1920 AddressRange inline_range;
1921 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
1922 func_addr = inline_range.GetBaseAddress();
1923 }
1924 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001925 else if (sc->symbol && sc->symbol->GetAddressRangePtr())
1926 func_addr = sc->symbol->GetAddressRangePtr()->GetBaseAddress();
1927 }
1928
1929 if (func_addr.IsValid())
Greg Clayton1b654882010-09-19 02:33:57 +00001930 {
1931 if (func_addr.GetSection() == format_addr.GetSection())
1932 {
1933 addr_t func_file_addr = func_addr.GetFileAddress();
1934 addr_t addr_file_addr = format_addr.GetFileAddress();
1935 if (addr_file_addr > func_file_addr)
Greg Clayton1b654882010-09-19 02:33:57 +00001936 s.Printf(" + %llu", addr_file_addr - func_file_addr);
Greg Clayton1b654882010-09-19 02:33:57 +00001937 else if (addr_file_addr < func_file_addr)
Greg Clayton1b654882010-09-19 02:33:57 +00001938 s.Printf(" - %llu", func_file_addr - addr_file_addr);
Greg Clayton0603aa92010-10-04 01:05:56 +00001939 var_success = true;
Greg Clayton1b654882010-09-19 02:33:57 +00001940 }
1941 else
Greg Clayton0603aa92010-10-04 01:05:56 +00001942 {
1943 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1944 if (target)
1945 {
1946 addr_t func_load_addr = func_addr.GetLoadAddress (target);
1947 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
1948 if (addr_load_addr > func_load_addr)
1949 s.Printf(" + %llu", addr_load_addr - func_load_addr);
1950 else if (addr_load_addr < func_load_addr)
1951 s.Printf(" - %llu", func_load_addr - addr_load_addr);
1952 var_success = true;
1953 }
1954 }
Greg Clayton1b654882010-09-19 02:33:57 +00001955 }
1956 }
1957 else
1958 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001959 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
Greg Clayton1b654882010-09-19 02:33:57 +00001960 addr_t vaddr = LLDB_INVALID_ADDRESS;
Greg Clayton0603aa92010-10-04 01:05:56 +00001961 if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
1962 vaddr = format_addr.GetLoadAddress (target);
Greg Clayton1b654882010-09-19 02:33:57 +00001963 if (vaddr == LLDB_INVALID_ADDRESS)
1964 vaddr = format_addr.GetFileAddress ();
1965
1966 if (vaddr != LLDB_INVALID_ADDRESS)
Greg Clayton0603aa92010-10-04 01:05:56 +00001967 {
Greg Clayton514487e2011-02-15 21:59:32 +00001968 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
Greg Clayton35f1a0d2010-11-19 04:16:11 +00001969 if (addr_width == 0)
1970 addr_width = 16;
1971 s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
Greg Clayton0603aa92010-10-04 01:05:56 +00001972 var_success = true;
1973 }
Greg Clayton1b654882010-09-19 02:33:57 +00001974 }
1975 }
1976 }
1977
1978 if (var_success == false)
1979 success = false;
1980 }
1981 p = var_name_end;
1982 }
1983 else
1984 break;
1985 }
1986 else
1987 {
1988 // We got a dollar sign with no '{' after it, it must just be a dollar sign
1989 s.PutChar(*p);
1990 }
1991 }
1992 else if (*p == '\\')
1993 {
1994 ++p; // skip the slash
1995 switch (*p)
1996 {
1997 case 'a': s.PutChar ('\a'); break;
1998 case 'b': s.PutChar ('\b'); break;
1999 case 'f': s.PutChar ('\f'); break;
2000 case 'n': s.PutChar ('\n'); break;
2001 case 'r': s.PutChar ('\r'); break;
2002 case 't': s.PutChar ('\t'); break;
2003 case 'v': s.PutChar ('\v'); break;
2004 case '\'': s.PutChar ('\''); break;
2005 case '\\': s.PutChar ('\\'); break;
2006 case '0':
2007 // 1 to 3 octal chars
2008 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002009 // Make a string that can hold onto the initial zero char,
2010 // up to 3 octal digits, and a terminating NULL.
2011 char oct_str[5] = { 0, 0, 0, 0, 0 };
2012
2013 int i;
2014 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
2015 oct_str[i] = p[i];
2016
2017 // We don't want to consume the last octal character since
2018 // the main for loop will do this for us, so we advance p by
2019 // one less than i (even if i is zero)
2020 p += i - 1;
2021 unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
2022 if (octal_value <= UINT8_MAX)
Greg Clayton1b654882010-09-19 02:33:57 +00002023 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002024 char octal_char = octal_value;
2025 s.Write (&octal_char, 1);
Greg Clayton1b654882010-09-19 02:33:57 +00002026 }
Greg Clayton1b654882010-09-19 02:33:57 +00002027 }
2028 break;
2029
2030 case 'x':
2031 // hex number in the format
Greg Clayton0603aa92010-10-04 01:05:56 +00002032 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00002033 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002034 ++p; // Skip the 'x'
Greg Clayton1b654882010-09-19 02:33:57 +00002035
Greg Clayton0603aa92010-10-04 01:05:56 +00002036 // Make a string that can hold onto two hex chars plus a
2037 // NULL terminator
2038 char hex_str[3] = { 0,0,0 };
2039 hex_str[0] = *p;
2040 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00002041 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002042 ++p; // Skip the first of the two hex chars
2043 hex_str[1] = *p;
2044 }
2045
2046 unsigned long hex_value = strtoul (hex_str, NULL, 16);
2047 if (hex_value <= UINT8_MAX)
Greg Clayton1b654882010-09-19 02:33:57 +00002048 s.PutChar (hex_value);
Greg Clayton0603aa92010-10-04 01:05:56 +00002049 }
2050 else
2051 {
2052 s.PutChar('x');
Greg Clayton1b654882010-09-19 02:33:57 +00002053 }
2054 break;
2055
2056 default:
Greg Clayton0603aa92010-10-04 01:05:56 +00002057 // Just desensitize any other character by just printing what
2058 // came after the '\'
2059 s << *p;
Greg Clayton1b654882010-09-19 02:33:57 +00002060 break;
2061
2062 }
2063
2064 }
2065 }
2066 if (end)
2067 *end = p;
2068 return success;
2069}
2070
2071#pragma mark Debugger::SettingsController
2072
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002073//--------------------------------------------------
Greg Clayton1b654882010-09-19 02:33:57 +00002074// class Debugger::SettingsController
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002075//--------------------------------------------------
2076
Greg Clayton1b654882010-09-19 02:33:57 +00002077Debugger::SettingsController::SettingsController () :
Greg Clayton4d122c42011-09-17 08:33:22 +00002078 UserSettingsController ("", UserSettingsControllerSP())
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002079{
Caroline Tice91123da2010-09-08 17:48:55 +00002080 m_default_settings.reset (new DebuggerInstanceSettings (*this, false,
2081 InstanceSettings::GetDefaultName().AsCString()));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002082}
2083
Greg Clayton1b654882010-09-19 02:33:57 +00002084Debugger::SettingsController::~SettingsController ()
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002085{
2086}
2087
2088
Greg Clayton4d122c42011-09-17 08:33:22 +00002089InstanceSettingsSP
Greg Clayton1b654882010-09-19 02:33:57 +00002090Debugger::SettingsController::CreateInstanceSettings (const char *instance_name)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002091{
Greg Claytondbe54502010-11-19 03:46:01 +00002092 DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*GetSettingsController(),
Caroline Tice91123da2010-09-08 17:48:55 +00002093 false, instance_name);
Greg Clayton4d122c42011-09-17 08:33:22 +00002094 InstanceSettingsSP new_settings_sp (new_settings);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002095 return new_settings_sp;
2096}
2097
Greg Clayton1b654882010-09-19 02:33:57 +00002098#pragma mark DebuggerInstanceSettings
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002099//--------------------------------------------------
2100// class DebuggerInstanceSettings
2101//--------------------------------------------------
2102
Greg Claytona7015092010-09-18 01:14:36 +00002103DebuggerInstanceSettings::DebuggerInstanceSettings
2104(
2105 UserSettingsController &owner,
2106 bool live_instance,
2107 const char *name
2108) :
Greg Clayton85851dd2010-12-04 00:10:17 +00002109 InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
Greg Claytona7015092010-09-18 01:14:36 +00002110 m_term_width (80),
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002111 m_prompt (),
Greg Clayton0603aa92010-10-04 01:05:56 +00002112 m_frame_format (),
2113 m_thread_format (),
Caroline Ticedaccaa92010-09-20 20:44:43 +00002114 m_script_lang (),
Jim Ingham3bcdb292010-10-04 22:44:14 +00002115 m_use_external_editor (false),
2116 m_auto_confirm_on (false)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002117{
Caroline Ticef20e8232010-09-09 18:26:37 +00002118 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
2119 // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers.
2120 // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
Caroline Tice9e41c152010-09-16 19:05:55 +00002121 // The same is true of CreateInstanceName().
2122
2123 if (GetInstanceName() == InstanceSettings::InvalidName())
2124 {
2125 ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
2126 m_owner.RegisterInstanceSettings (this);
2127 }
Caroline Ticef20e8232010-09-09 18:26:37 +00002128
2129 if (live_instance)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002130 {
Greg Clayton4d122c42011-09-17 08:33:22 +00002131 const InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002132 CopyInstanceSettings (pending_settings, false);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002133 }
2134}
2135
2136DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
Greg Clayton99d0faf2010-11-18 23:32:35 +00002137 InstanceSettings (*Debugger::GetSettingsController(), CreateInstanceName ().AsCString()),
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002138 m_prompt (rhs.m_prompt),
Greg Clayton0603aa92010-10-04 01:05:56 +00002139 m_frame_format (rhs.m_frame_format),
2140 m_thread_format (rhs.m_thread_format),
Caroline Ticedaccaa92010-09-20 20:44:43 +00002141 m_script_lang (rhs.m_script_lang),
Jim Ingham3bcdb292010-10-04 22:44:14 +00002142 m_use_external_editor (rhs.m_use_external_editor),
2143 m_auto_confirm_on(rhs.m_auto_confirm_on)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002144{
Greg Clayton4d122c42011-09-17 08:33:22 +00002145 const InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002146 CopyInstanceSettings (pending_settings, false);
2147 m_owner.RemovePendingSettings (m_instance_name);
2148}
2149
2150DebuggerInstanceSettings::~DebuggerInstanceSettings ()
2151{
2152}
2153
2154DebuggerInstanceSettings&
2155DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
2156{
2157 if (this != &rhs)
2158 {
Greg Clayton1b654882010-09-19 02:33:57 +00002159 m_term_width = rhs.m_term_width;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002160 m_prompt = rhs.m_prompt;
Greg Clayton0603aa92010-10-04 01:05:56 +00002161 m_frame_format = rhs.m_frame_format;
2162 m_thread_format = rhs.m_thread_format;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002163 m_script_lang = rhs.m_script_lang;
Caroline Ticedaccaa92010-09-20 20:44:43 +00002164 m_use_external_editor = rhs.m_use_external_editor;
Jim Ingham3bcdb292010-10-04 22:44:14 +00002165 m_auto_confirm_on = rhs.m_auto_confirm_on;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002166 }
2167
2168 return *this;
2169}
2170
Greg Clayton1b654882010-09-19 02:33:57 +00002171bool
2172DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err)
2173{
2174 bool valid = false;
2175
2176 // Verify we have a value string.
2177 if (value == NULL || value[0] == '\0')
2178 {
Greg Clayton86edbf42011-10-26 00:56:27 +00002179 err.SetErrorString ("missing value, can't set terminal width without a value");
Greg Clayton1b654882010-09-19 02:33:57 +00002180 }
2181 else
2182 {
2183 char *end = NULL;
2184 const uint32_t width = ::strtoul (value, &end, 0);
2185
Johnny Chenea9fc182010-09-20 16:36:43 +00002186 if (end && end[0] == '\0')
Greg Clayton1b654882010-09-19 02:33:57 +00002187 {
Johnny Chen433d7742010-09-20 17:04:41 +00002188 if (width >= 10 && width <= 1024)
Greg Clayton1b654882010-09-19 02:33:57 +00002189 valid = true;
2190 else
Greg Clayton86edbf42011-10-26 00:56:27 +00002191 err.SetErrorString ("invalid term-width value; value must be between 10 and 1024");
Greg Clayton1b654882010-09-19 02:33:57 +00002192 }
2193 else
Greg Clayton86edbf42011-10-26 00:56:27 +00002194 err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string", value);
Greg Clayton1b654882010-09-19 02:33:57 +00002195 }
2196
2197 return valid;
2198}
2199
2200
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002201void
2202DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
2203 const char *index_value,
2204 const char *value,
2205 const ConstString &instance_name,
2206 const SettingEntry &entry,
Greg Claytone0d378b2011-03-24 21:19:54 +00002207 VarSetOperationType op,
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002208 Error &err,
2209 bool pending)
2210{
Greg Clayton0603aa92010-10-04 01:05:56 +00002211
2212 if (var_name == TermWidthVarName())
2213 {
2214 if (ValidTermWidthValue (value, err))
2215 {
2216 m_term_width = ::strtoul (value, NULL, 0);
2217 }
2218 }
2219 else if (var_name == PromptVarName())
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002220 {
Caroline Tice101c7c22010-09-09 06:25:08 +00002221 UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002222 if (!pending)
2223 {
Caroline Tice49e27372010-09-07 18:35:40 +00002224 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to
2225 // strip off the brackets before passing it to BroadcastPromptChange.
2226
2227 std::string tmp_instance_name (instance_name.AsCString());
2228 if ((tmp_instance_name[0] == '[')
2229 && (tmp_instance_name[instance_name.GetLength() - 1] == ']'))
2230 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2);
2231 ConstString new_name (tmp_instance_name.c_str());
2232
2233 BroadcastPromptChange (new_name, m_prompt.c_str());
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002234 }
2235 }
Greg Clayton0603aa92010-10-04 01:05:56 +00002236 else if (var_name == GetFrameFormatName())
2237 {
2238 UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err);
2239 }
2240 else if (var_name == GetThreadFormatName())
2241 {
2242 UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err);
2243 }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002244 else if (var_name == ScriptLangVarName())
2245 {
2246 bool success;
2247 m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
2248 &success);
2249 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00002250 else if (var_name == UseExternalEditorVarName ())
2251 {
Greg Clayton385aa282011-04-22 03:55:06 +00002252 UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err);
Caroline Ticedaccaa92010-09-20 20:44:43 +00002253 }
Jim Ingham3bcdb292010-10-04 22:44:14 +00002254 else if (var_name == AutoConfirmName ())
2255 {
Greg Clayton385aa282011-04-22 03:55:06 +00002256 UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
Jim Ingham3bcdb292010-10-04 22:44:14 +00002257 }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002258}
2259
Caroline Tice12cecd72010-09-20 21:37:42 +00002260bool
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002261DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
2262 const ConstString &var_name,
Caroline Ticedaccaa92010-09-20 20:44:43 +00002263 StringList &value,
Caroline Tice12cecd72010-09-20 21:37:42 +00002264 Error *err)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002265{
2266 if (var_name == PromptVarName())
2267 {
Greg Clayton0603aa92010-10-04 01:05:56 +00002268 value.AppendString (m_prompt.c_str(), m_prompt.size());
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002269
2270 }
2271 else if (var_name == ScriptLangVarName())
2272 {
2273 value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
2274 }
Caroline Tice101c7c22010-09-09 06:25:08 +00002275 else if (var_name == TermWidthVarName())
2276 {
2277 StreamString width_str;
2278 width_str.Printf ("%d", m_term_width);
2279 value.AppendString (width_str.GetData());
2280 }
Greg Clayton0603aa92010-10-04 01:05:56 +00002281 else if (var_name == GetFrameFormatName ())
2282 {
2283 value.AppendString(m_frame_format.c_str(), m_frame_format.size());
2284 }
2285 else if (var_name == GetThreadFormatName ())
2286 {
2287 value.AppendString(m_thread_format.c_str(), m_thread_format.size());
2288 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00002289 else if (var_name == UseExternalEditorVarName())
2290 {
2291 if (m_use_external_editor)
2292 value.AppendString ("true");
2293 else
2294 value.AppendString ("false");
2295 }
Jim Ingham3bcdb292010-10-04 22:44:14 +00002296 else if (var_name == AutoConfirmName())
2297 {
2298 if (m_auto_confirm_on)
2299 value.AppendString ("true");
2300 else
2301 value.AppendString ("false");
2302 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00002303 else
Caroline Tice12cecd72010-09-20 21:37:42 +00002304 {
2305 if (err)
2306 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
2307 return false;
2308 }
2309 return true;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002310}
2311
2312void
Greg Clayton4d122c42011-09-17 08:33:22 +00002313DebuggerInstanceSettings::CopyInstanceSettings (const InstanceSettingsSP &new_settings,
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002314 bool pending)
2315{
2316 if (new_settings.get() == NULL)
2317 return;
2318
2319 DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
2320
2321 m_prompt = new_debugger_settings->m_prompt;
2322 if (!pending)
Caroline Tice49e27372010-09-07 18:35:40 +00002323 {
2324 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to
2325 // strip off the brackets before passing it to BroadcastPromptChange.
2326
2327 std::string tmp_instance_name (m_instance_name.AsCString());
2328 if ((tmp_instance_name[0] == '[')
2329 && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']'))
2330 tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2);
2331 ConstString new_name (tmp_instance_name.c_str());
2332
2333 BroadcastPromptChange (new_name, m_prompt.c_str());
2334 }
Greg Clayton0603aa92010-10-04 01:05:56 +00002335 m_frame_format = new_debugger_settings->m_frame_format;
2336 m_thread_format = new_debugger_settings->m_thread_format;
Caroline Ticedaccaa92010-09-20 20:44:43 +00002337 m_term_width = new_debugger_settings->m_term_width;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002338 m_script_lang = new_debugger_settings->m_script_lang;
Caroline Ticedaccaa92010-09-20 20:44:43 +00002339 m_use_external_editor = new_debugger_settings->m_use_external_editor;
Jim Ingham3bcdb292010-10-04 22:44:14 +00002340 m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002341}
2342
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002343
2344bool
2345DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
2346{
2347 std::string tmp_prompt;
2348
2349 if (new_prompt != NULL)
2350 {
2351 tmp_prompt = new_prompt ;
2352 int len = tmp_prompt.size();
2353 if (len > 1
2354 && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
2355 && (tmp_prompt[len-1] == tmp_prompt[0]))
2356 {
2357 tmp_prompt = tmp_prompt.substr(1,len-2);
2358 }
2359 len = tmp_prompt.size();
2360 if (tmp_prompt[len-1] != ' ')
2361 tmp_prompt.append(" ");
2362 }
2363 EventSP new_event_sp;
2364 new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
2365 new EventDataBytes (tmp_prompt.c_str())));
2366
2367 if (instance_name.GetLength() != 0)
2368 {
2369 // Set prompt for a particular instance.
2370 Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
2371 if (dbg != NULL)
2372 {
2373 dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
2374 }
2375 }
2376
2377 return true;
2378}
2379
2380const ConstString
2381DebuggerInstanceSettings::CreateInstanceName ()
2382{
2383 static int instance_count = 1;
2384 StreamString sstr;
2385
2386 sstr.Printf ("debugger_%d", instance_count);
2387 ++instance_count;
2388
2389 const ConstString ret_val (sstr.GetData());
2390
2391 return ret_val;
2392}
2393
2394const ConstString &
2395DebuggerInstanceSettings::PromptVarName ()
2396{
2397 static ConstString prompt_var_name ("prompt");
2398
2399 return prompt_var_name;
2400}
2401
2402const ConstString &
Greg Clayton0603aa92010-10-04 01:05:56 +00002403DebuggerInstanceSettings::GetFrameFormatName ()
2404{
2405 static ConstString prompt_var_name ("frame-format");
2406
2407 return prompt_var_name;
2408}
2409
2410const ConstString &
2411DebuggerInstanceSettings::GetThreadFormatName ()
2412{
2413 static ConstString prompt_var_name ("thread-format");
2414
2415 return prompt_var_name;
2416}
2417
2418const ConstString &
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002419DebuggerInstanceSettings::ScriptLangVarName ()
2420{
2421 static ConstString script_lang_var_name ("script-lang");
2422
2423 return script_lang_var_name;
2424}
2425
Caroline Tice101c7c22010-09-09 06:25:08 +00002426const ConstString &
2427DebuggerInstanceSettings::TermWidthVarName ()
2428{
2429 static ConstString term_width_var_name ("term-width");
2430
2431 return term_width_var_name;
2432}
2433
Caroline Ticedaccaa92010-09-20 20:44:43 +00002434const ConstString &
2435DebuggerInstanceSettings::UseExternalEditorVarName ()
2436{
2437 static ConstString use_external_editor_var_name ("use-external-editor");
2438
2439 return use_external_editor_var_name;
2440}
2441
Jim Ingham3bcdb292010-10-04 22:44:14 +00002442const ConstString &
2443DebuggerInstanceSettings::AutoConfirmName ()
2444{
2445 static ConstString use_external_editor_var_name ("auto-confirm");
2446
2447 return use_external_editor_var_name;
2448}
2449
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002450//--------------------------------------------------
Greg Clayton1b654882010-09-19 02:33:57 +00002451// SettingsController Variable Tables
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002452//--------------------------------------------------
2453
2454
2455SettingEntry
Greg Clayton1b654882010-09-19 02:33:57 +00002456Debugger::SettingsController::global_settings_table[] =
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002457{
2458 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
Caroline Tice101c7c22010-09-09 06:25:08 +00002459 // The Debugger level global table should always be empty; all Debugger settable variables should be instance
2460 // variables.
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002461 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
2462};
2463
Greg Claytonbb562b12010-10-04 02:44:26 +00002464#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}"
Greg Clayton0603aa92010-10-04 01:05:56 +00002465#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002466
Greg Clayton0603aa92010-10-04 01:05:56 +00002467#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
2468 "{, ${frame.pc}}"\
2469 MODULE_WITH_FUNC\
Greg Claytoncf4b9072010-10-04 17:04:23 +00002470 FILE_AND_LINE\
Greg Clayton0603aa92010-10-04 01:05:56 +00002471 "{, stop reason = ${thread.stop-reason}}"\
Greg Clayton0603aa92010-10-04 01:05:56 +00002472 "\\n"
2473
Greg Clayton315d2ca2010-11-02 01:53:21 +00002474//#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
2475// "{, ${frame.pc}}"\
2476// MODULE_WITH_FUNC\
2477// FILE_AND_LINE\
2478// "{, stop reason = ${thread.stop-reason}}"\
2479// "{, name = ${thread.name}}"\
2480// "{, queue = ${thread.queue}}"\
2481// "\\n"
2482
Greg Clayton0603aa92010-10-04 01:05:56 +00002483#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
2484 MODULE_WITH_FUNC\
2485 FILE_AND_LINE\
2486 "\\n"
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002487
2488SettingEntry
Greg Clayton1b654882010-09-19 02:33:57 +00002489Debugger::SettingsController::instance_settings_table[] =
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002490{
Greg Clayton0603aa92010-10-04 01:05:56 +00002491// NAME Setting variable type Default Enum Init'd Hidden Help
2492// ======================= ======================= ====================== ==== ====== ====== ======================
Greg Clayton0603aa92010-10-04 01:05:56 +00002493{ "frame-format", eSetVarTypeString, DEFAULT_FRAME_FORMAT, NULL, false, false, "The default frame format string to use when displaying thread information." },
Greg Clayton54180392010-10-22 21:15:00 +00002494{ "prompt", eSetVarTypeString, "(lldb) ", NULL, false, false, "The debugger command line prompt displayed for the user." },
Jim Ingham3bcdb292010-10-04 22:44:14 +00002495{ "script-lang", eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." },
2496{ "term-width", eSetVarTypeInt, "80" , NULL, false, false, "The maximum number of columns to use for displaying text." },
Greg Clayton0603aa92010-10-04 01:05:56 +00002497{ "thread-format", eSetVarTypeString, DEFAULT_THREAD_FORMAT, NULL, false, false, "The default thread format string to use when displaying thread information." },
Jim Ingham06e827c2010-11-11 19:26:09 +00002498{ "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." },
2499{ "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." },
Greg Clayton0603aa92010-10-04 01:05:56 +00002500{ NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00002501};