1 //===-- 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 
10 #include "lldb/lldb-private.h"
11 #include "lldb/Core/ConnectionFileDescriptor.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/InputReader.h"
14 #include "lldb/Core/State.h"
15 #include "lldb/Core/StreamString.h"
16 #include "lldb/Core/Timer.h"
17 #include "lldb/Interpreter/CommandInterpreter.h"
18 #include "lldb/Target/TargetList.h"
19 #include "lldb/Target/Process.h"
20 #include "lldb/Target/RegisterContext.h"
21 #include "lldb/Target/StopInfo.h"
22 #include "lldb/Target/Thread.h"
23 
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 
29 static uint32_t g_shared_debugger_refcount = 0;
30 static lldb::user_id_t g_unique_id = 1;
31 
32 #pragma mark Static Functions
33 
34 static Mutex &
35 GetDebuggerListMutex ()
36 {
37     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
38     return g_mutex;
39 }
40 
41 typedef std::vector<DebuggerSP> DebuggerList;
42 
43 static DebuggerList &
44 GetDebuggerList()
45 {
46     // hide the static debugger list inside a singleton accessor to avoid
47     // global init contructors
48     static DebuggerList g_list;
49     return g_list;
50 }
51 
52 
53 #pragma mark Debugger
54 
55 UserSettingsControllerSP &
56 Debugger::GetSettingsController ()
57 {
58     static UserSettingsControllerSP g_settings_controller;
59     return g_settings_controller;
60 }
61 
62 int
63 Debugger::TestDebuggerRefCount ()
64 {
65     return g_shared_debugger_refcount;
66 }
67 
68 void
69 Debugger::Initialize ()
70 {
71     if (g_shared_debugger_refcount == 0)
72     {
73         UserSettingsControllerSP &usc = GetSettingsController();
74         usc.reset (new SettingsController);
75         UserSettingsController::InitializeSettingsController (usc,
76                                                               SettingsController::global_settings_table,
77                                                               SettingsController::instance_settings_table);
78         lldb_private::Initialize();
79     }
80     g_shared_debugger_refcount++;
81 
82 }
83 
84 void
85 Debugger::Terminate ()
86 {
87     if (g_shared_debugger_refcount > 0)
88     {
89         g_shared_debugger_refcount--;
90         if (g_shared_debugger_refcount == 0)
91         {
92             lldb_private::WillTerminate();
93             lldb_private::Terminate();
94             UserSettingsControllerSP &usc = GetSettingsController();
95             UserSettingsController::FinalizeSettingsController (usc);
96             usc.reset();
97 
98             // Clear our master list of debugger objects
99             Mutex::Locker locker (GetDebuggerListMutex ());
100             GetDebuggerList().clear();
101         }
102     }
103 }
104 
105 DebuggerSP
106 Debugger::CreateInstance ()
107 {
108     DebuggerSP debugger_sp (new Debugger);
109     // Scope for locker
110     {
111         Mutex::Locker locker (GetDebuggerListMutex ());
112         GetDebuggerList().push_back(debugger_sp);
113     }
114     return debugger_sp;
115 }
116 
117 void
118 Debugger::Destroy (lldb::DebuggerSP &debugger_sp)
119 {
120     if (debugger_sp.get() == NULL)
121         return;
122 
123     Mutex::Locker locker (GetDebuggerListMutex ());
124     DebuggerList &debugger_list = GetDebuggerList ();
125     DebuggerList::iterator pos, end = debugger_list.end();
126     for (pos = debugger_list.begin (); pos != end; ++pos)
127     {
128         if ((*pos).get() == debugger_sp.get())
129         {
130             debugger_list.erase (pos);
131             return;
132         }
133     }
134 
135 }
136 
137 lldb::DebuggerSP
138 Debugger::GetSP ()
139 {
140     lldb::DebuggerSP debugger_sp;
141 
142     Mutex::Locker locker (GetDebuggerListMutex ());
143     DebuggerList &debugger_list = GetDebuggerList();
144     DebuggerList::iterator pos, end = debugger_list.end();
145     for (pos = debugger_list.begin(); pos != end; ++pos)
146     {
147         if ((*pos).get() == this)
148         {
149             debugger_sp = *pos;
150             break;
151         }
152     }
153     return debugger_sp;
154 }
155 
156 lldb::DebuggerSP
157 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
158 {
159     lldb::DebuggerSP debugger_sp;
160 
161     Mutex::Locker locker (GetDebuggerListMutex ());
162     DebuggerList &debugger_list = GetDebuggerList();
163     DebuggerList::iterator pos, end = debugger_list.end();
164 
165     for (pos = debugger_list.begin(); pos != end; ++pos)
166     {
167         if ((*pos).get()->m_instance_name == instance_name)
168         {
169             debugger_sp = *pos;
170             break;
171         }
172     }
173     return debugger_sp;
174 }
175 
176 TargetSP
177 Debugger::FindTargetWithProcessID (lldb::pid_t pid)
178 {
179     lldb::TargetSP target_sp;
180     Mutex::Locker locker (GetDebuggerListMutex ());
181     DebuggerList &debugger_list = GetDebuggerList();
182     DebuggerList::iterator pos, end = debugger_list.end();
183     for (pos = debugger_list.begin(); pos != end; ++pos)
184     {
185         target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
186         if (target_sp)
187             break;
188     }
189     return target_sp;
190 }
191 
192 
193 Debugger::Debugger () :
194     UserID (g_unique_id++),
195     DebuggerInstanceSettings (*GetSettingsController()),
196     m_input_comm("debugger.input"),
197     m_input_file (),
198     m_output_file (),
199     m_error_file (),
200     m_target_list (),
201     m_listener ("lldb.Debugger"),
202     m_source_manager (),
203     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
204     m_exe_ctx (),
205     m_input_readers (),
206     m_input_reader_data ()
207 {
208     m_input_comm.SetCloseOnEOF(false);
209     m_command_interpreter_ap->Initialize ();
210 }
211 
212 Debugger::~Debugger ()
213 {
214     CleanUpInputReaders();
215     int num_targets = m_target_list.GetNumTargets();
216     for (int i = 0; i < num_targets; i++)
217     {
218         ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
219         if (process_sp)
220             process_sp->Destroy();
221     }
222     DisconnectInput();
223 }
224 
225 
226 bool
227 Debugger::GetAsyncExecution ()
228 {
229     return !m_command_interpreter_ap->GetSynchronous();
230 }
231 
232 void
233 Debugger::SetAsyncExecution (bool async_execution)
234 {
235     m_command_interpreter_ap->SetSynchronous (!async_execution);
236 }
237 
238 void
239 Debugger::DisconnectInput()
240 {
241     m_input_comm.Clear ();
242 }
243 
244 void
245 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
246 {
247     m_input_file.SetFileHandle (fh, tranfer_ownership);
248     if (m_input_file.GetFileHandle() == NULL)
249         m_input_file.SetFileHandle (stdin, false);
250 
251     // Disconnect from any old connection if we had one
252     m_input_comm.Disconnect ();
253     m_input_comm.SetConnection (new ConnectionFileDescriptor (::fileno (GetInputFileHandle()), true));
254     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
255 
256     Error error;
257     if (m_input_comm.StartReadThread (&error) == false)
258     {
259         FILE *err_fh = GetErrorFileHandle();
260         if (err_fh)
261         {
262             ::fprintf (err_fh, "error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
263             exit(1);
264         }
265     }
266 
267 }
268 
269 FILE *
270 Debugger::GetInputFileHandle ()
271 {
272     return m_input_file.GetFileHandle();
273 }
274 
275 
276 void
277 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
278 {
279     m_output_file.SetFileHandle (fh, tranfer_ownership);
280     if (m_output_file.GetFileHandle() == NULL)
281         m_output_file.SetFileHandle (stdin, false);
282 
283     GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
284 }
285 
286 FILE *
287 Debugger::GetOutputFileHandle ()
288 {
289     return m_output_file.GetFileHandle();
290 }
291 
292 void
293 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
294 {
295     m_error_file.SetFileHandle (fh, tranfer_ownership);
296     if (m_error_file.GetFileHandle() == NULL)
297         m_error_file.SetFileHandle (stdin, false);
298 }
299 
300 
301 FILE *
302 Debugger::GetErrorFileHandle ()
303 {
304     return m_error_file.GetFileHandle();
305 }
306 
307 CommandInterpreter &
308 Debugger::GetCommandInterpreter ()
309 {
310     assert (m_command_interpreter_ap.get());
311     return *m_command_interpreter_ap;
312 }
313 
314 Listener &
315 Debugger::GetListener ()
316 {
317     return m_listener;
318 }
319 
320 
321 TargetSP
322 Debugger::GetSelectedTarget ()
323 {
324     return m_target_list.GetSelectedTarget ();
325 }
326 
327 ExecutionContext
328 Debugger::GetSelectedExecutionContext ()
329 {
330     ExecutionContext exe_ctx;
331     exe_ctx.Clear();
332 
333     lldb::TargetSP target_sp = GetSelectedTarget();
334     exe_ctx.target = target_sp.get();
335 
336     if (target_sp)
337     {
338         exe_ctx.process = target_sp->GetProcessSP().get();
339         if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
340         {
341             exe_ctx.thread = exe_ctx.process->GetThreadList().GetSelectedThread().get();
342             if (exe_ctx.thread == NULL)
343                 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
344             if (exe_ctx.thread)
345             {
346                 exe_ctx.frame = exe_ctx.thread->GetSelectedFrame().get();
347                 if (exe_ctx.frame == NULL)
348                     exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
349             }
350         }
351     }
352     return exe_ctx;
353 
354 }
355 
356 SourceManager &
357 Debugger::GetSourceManager ()
358 {
359     return m_source_manager;
360 }
361 
362 
363 TargetList&
364 Debugger::GetTargetList ()
365 {
366     return m_target_list;
367 }
368 
369 void
370 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
371 {
372     if (bytes_len > 0)
373         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
374     else
375         ((Debugger *)baton)->DispatchInputEndOfFile ();
376 }
377 
378 
379 void
380 Debugger::DispatchInput (const char *bytes, size_t bytes_len)
381 {
382     if (bytes == NULL || bytes_len == 0)
383         return;
384 
385     WriteToDefaultReader (bytes, bytes_len);
386 }
387 
388 void
389 Debugger::DispatchInputInterrupt ()
390 {
391     m_input_reader_data.clear();
392 
393     if (!m_input_readers.empty())
394     {
395         while (CheckIfTopInputReaderIsDone ()) ;
396 
397         InputReaderSP reader_sp(m_input_readers.top());
398         if (reader_sp)
399             reader_sp->Notify (eInputReaderInterrupt);
400 
401         while (CheckIfTopInputReaderIsDone ()) ;
402     }
403 }
404 
405 void
406 Debugger::DispatchInputEndOfFile ()
407 {
408     m_input_reader_data.clear();
409 
410     if (!m_input_readers.empty())
411     {
412         while (CheckIfTopInputReaderIsDone ()) ;
413 
414         InputReaderSP reader_sp(m_input_readers.top());
415         if (reader_sp)
416             reader_sp->Notify (eInputReaderEndOfFile);
417 
418         while (CheckIfTopInputReaderIsDone ()) ;
419     }
420 }
421 
422 void
423 Debugger::CleanUpInputReaders ()
424 {
425     m_input_reader_data.clear();
426 
427     while (m_input_readers.size() > 1)
428     {
429         while (CheckIfTopInputReaderIsDone ()) ;
430 
431         InputReaderSP reader_sp (m_input_readers.top());
432         if (reader_sp)
433         {
434             reader_sp->Notify (eInputReaderEndOfFile);
435             reader_sp->SetIsDone (true);
436         }
437     }
438 }
439 
440 void
441 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
442 {
443     if (bytes && bytes_len)
444         m_input_reader_data.append (bytes, bytes_len);
445 
446     if (m_input_reader_data.empty())
447         return;
448 
449     while (!m_input_readers.empty() && !m_input_reader_data.empty())
450     {
451         while (CheckIfTopInputReaderIsDone ())
452             /* Do nothing. */;
453 
454         // Get the input reader from the top of the stack
455         InputReaderSP reader_sp(m_input_readers.top());
456 
457         if (!reader_sp)
458             break;
459 
460         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
461                                                           m_input_reader_data.size());
462         if (bytes_handled)
463         {
464             m_input_reader_data.erase (0, bytes_handled);
465         }
466         else
467         {
468             // No bytes were handled, we might not have reached our
469             // granularity, just return and wait for more data
470             break;
471         }
472     }
473 
474     // Flush out any input readers that are donesvn
475     while (CheckIfTopInputReaderIsDone ())
476         /* Do nothing. */;
477 
478 }
479 
480 void
481 Debugger::PushInputReader (const InputReaderSP& reader_sp)
482 {
483     if (!reader_sp)
484         return;
485     if (!m_input_readers.empty())
486     {
487         // Deactivate the old top reader
488         InputReaderSP top_reader_sp (m_input_readers.top());
489         if (top_reader_sp)
490             top_reader_sp->Notify (eInputReaderDeactivate);
491     }
492     m_input_readers.push (reader_sp);
493     reader_sp->Notify (eInputReaderActivate);
494     ActivateInputReader (reader_sp);
495 }
496 
497 bool
498 Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
499 {
500     bool result = false;
501 
502     // The reader on the stop of the stack is done, so let the next
503     // read on the stack referesh its prompt and if there is one...
504     if (!m_input_readers.empty())
505     {
506         InputReaderSP reader_sp(m_input_readers.top());
507 
508         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
509         {
510             m_input_readers.pop ();
511             reader_sp->Notify (eInputReaderDeactivate);
512             reader_sp->Notify (eInputReaderDone);
513             result = true;
514 
515             if (!m_input_readers.empty())
516             {
517                 reader_sp = m_input_readers.top();
518                 if (reader_sp)
519                 {
520                     ActivateInputReader (reader_sp);
521                     reader_sp->Notify (eInputReaderReactivate);
522                 }
523             }
524         }
525     }
526     return result;
527 }
528 
529 bool
530 Debugger::CheckIfTopInputReaderIsDone ()
531 {
532     bool result = false;
533     if (!m_input_readers.empty())
534     {
535         InputReaderSP reader_sp(m_input_readers.top());
536 
537         if (reader_sp && reader_sp->IsDone())
538         {
539             result = true;
540             PopInputReader (reader_sp);
541         }
542     }
543     return result;
544 }
545 
546 void
547 Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
548 {
549     FILE *in_fh = GetInputFileHandle();
550 
551     if (in_fh)
552     {
553         struct termios in_fh_termios;
554         int in_fd = fileno (in_fh);
555         if (::tcgetattr(in_fd, &in_fh_termios) == 0)
556         {
557             if (reader_sp->GetEcho())
558                 in_fh_termios.c_lflag |= ECHO;  // Turn on echoing
559             else
560                 in_fh_termios.c_lflag &= ~ECHO; // Turn off echoing
561 
562             switch (reader_sp->GetGranularity())
563             {
564             case eInputReaderGranularityByte:
565             case eInputReaderGranularityWord:
566                 in_fh_termios.c_lflag &= ~ICANON;   // Get one char at a time
567                 break;
568 
569             case eInputReaderGranularityLine:
570             case eInputReaderGranularityAll:
571                 in_fh_termios.c_lflag |= ICANON;   // Get lines at a time
572                 break;
573 
574             default:
575                 break;
576             }
577             ::tcsetattr (in_fd, TCSANOW, &in_fh_termios);
578         }
579     }
580 }
581 
582 void
583 Debugger::UpdateExecutionContext (ExecutionContext *override_context)
584 {
585     m_exe_ctx.Clear();
586 
587     if (override_context != NULL)
588     {
589         m_exe_ctx.target = override_context->target;
590         m_exe_ctx.process = override_context->process;
591         m_exe_ctx.thread = override_context->thread;
592         m_exe_ctx.frame = override_context->frame;
593     }
594     else
595     {
596         TargetSP target_sp (GetSelectedTarget());
597         if (target_sp)
598         {
599             m_exe_ctx.target = target_sp.get();
600             m_exe_ctx.process = target_sp->GetProcessSP().get();
601             if (m_exe_ctx.process && m_exe_ctx.process->IsAlive() && !m_exe_ctx.process->IsRunning())
602             {
603                 m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetSelectedThread().get();
604                 if (m_exe_ctx.thread == NULL)
605                 {
606                     m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
607                     // If we didn't have a selected thread, select one here.
608                     if (m_exe_ctx.thread != NULL)
609                         m_exe_ctx.process->GetThreadList().SetSelectedThreadByID(m_exe_ctx.thread->GetID());
610                 }
611                 if (m_exe_ctx.thread)
612                 {
613                     m_exe_ctx.frame = m_exe_ctx.thread->GetSelectedFrame().get();
614                     if (m_exe_ctx.frame == NULL)
615                     {
616                         m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get();
617                         // If we didn't have a selected frame select one here.
618                         if (m_exe_ctx.frame != NULL)
619                             m_exe_ctx.thread->SetSelectedFrame(m_exe_ctx.frame);
620                     }
621                 }
622             }
623         }
624     }
625 }
626 
627 DebuggerSP
628 Debugger::FindDebuggerWithID (lldb::user_id_t id)
629 {
630     lldb::DebuggerSP debugger_sp;
631 
632     Mutex::Locker locker (GetDebuggerListMutex ());
633     DebuggerList &debugger_list = GetDebuggerList();
634     DebuggerList::iterator pos, end = debugger_list.end();
635     for (pos = debugger_list.begin(); pos != end; ++pos)
636     {
637         if ((*pos).get()->GetID() == id)
638         {
639             debugger_sp = *pos;
640             break;
641         }
642     }
643     return debugger_sp;
644 }
645 
646 static void
647 TestPromptFormats (StackFrame *frame)
648 {
649     if (frame == NULL)
650         return;
651 
652     StreamString s;
653     const char *prompt_format =
654     "{addr = '${addr}'\n}"
655     "{process.id = '${process.id}'\n}"
656     "{process.name = '${process.name}'\n}"
657     "{process.file.basename = '${process.file.basename}'\n}"
658     "{process.file.fullpath = '${process.file.fullpath}'\n}"
659     "{thread.id = '${thread.id}'\n}"
660     "{thread.index = '${thread.index}'\n}"
661     "{thread.name = '${thread.name}'\n}"
662     "{thread.queue = '${thread.queue}'\n}"
663     "{thread.stop-reason = '${thread.stop-reason}'\n}"
664     "{target.arch = '${target.arch}'\n}"
665     "{module.file.basename = '${module.file.basename}'\n}"
666     "{module.file.fullpath = '${module.file.fullpath}'\n}"
667     "{file.basename = '${file.basename}'\n}"
668     "{file.fullpath = '${file.fullpath}'\n}"
669     "{frame.index = '${frame.index}'\n}"
670     "{frame.pc = '${frame.pc}'\n}"
671     "{frame.sp = '${frame.sp}'\n}"
672     "{frame.fp = '${frame.fp}'\n}"
673     "{frame.flags = '${frame.flags}'\n}"
674     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
675     "{frame.reg.rip = '${frame.reg.rip}'\n}"
676     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
677     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
678     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
679     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
680     "{frame.reg.carp = '${frame.reg.carp}'\n}"
681     "{function.id = '${function.id}'\n}"
682     "{function.name = '${function.name}'\n}"
683     "{function.addr-offset = '${function.addr-offset}'\n}"
684     "{function.line-offset = '${function.line-offset}'\n}"
685     "{function.pc-offset = '${function.pc-offset}'\n}"
686     "{line.file.basename = '${line.file.basename}'\n}"
687     "{line.file.fullpath = '${line.file.fullpath}'\n}"
688     "{line.number = '${line.number}'\n}"
689     "{line.start-addr = '${line.start-addr}'\n}"
690     "{line.end-addr = '${line.end-addr}'\n}"
691 ;
692 
693     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
694     ExecutionContext exe_ctx;
695     frame->CalculateExecutionContext(exe_ctx);
696     const char *end = NULL;
697     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
698     {
699         printf("%s\n", s.GetData());
700     }
701     else
702     {
703         printf ("error: at '%s'\n", end);
704         printf ("what we got: %s\n", s.GetData());
705     }
706 }
707 
708 bool
709 Debugger::FormatPrompt
710 (
711     const char *format,
712     const SymbolContext *sc,
713     const ExecutionContext *exe_ctx,
714     const Address *addr,
715     Stream &s,
716     const char **end
717 )
718 {
719     bool success = true;
720     const char *p;
721     for (p = format; *p != '\0'; ++p)
722     {
723         size_t non_special_chars = ::strcspn (p, "${}\\");
724         if (non_special_chars > 0)
725         {
726             if (success)
727                 s.Write (p, non_special_chars);
728             p += non_special_chars;
729         }
730 
731         if (*p == '\0')
732         {
733             break;
734         }
735         else if (*p == '{')
736         {
737             // Start a new scope that must have everything it needs if it is to
738             // to make it into the final output stream "s". If you want to make
739             // a format that only prints out the function or symbol name if there
740             // is one in the symbol context you can use:
741             //      "{function =${function.name}}"
742             // The first '{' starts a new scope that end with the matching '}' at
743             // the end of the string. The contents "function =${function.name}"
744             // will then be evaluated and only be output if there is a function
745             // or symbol with a valid name.
746             StreamString sub_strm;
747 
748             ++p;  // Skip the '{'
749 
750             if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p))
751             {
752                 // The stream had all it needed
753                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
754             }
755             if (*p != '}')
756             {
757                 success = false;
758                 break;
759             }
760         }
761         else if (*p == '}')
762         {
763             // End of a enclosing scope
764             break;
765         }
766         else if (*p == '$')
767         {
768             // We have a prompt variable to print
769             ++p;
770             if (*p == '{')
771             {
772                 ++p;
773                 const char *var_name_begin = p;
774                 const char *var_name_end = ::strchr (p, '}');
775 
776                 if (var_name_end && var_name_begin < var_name_end)
777                 {
778                     // if we have already failed to parse, skip this variable
779                     if (success)
780                     {
781                         const char *cstr = NULL;
782                         Address format_addr;
783                         bool calculate_format_addr_function_offset = false;
784                         // Set reg_kind and reg_num to invalid values
785                         RegisterKind reg_kind = kNumRegisterKinds;
786                         uint32_t reg_num = LLDB_INVALID_REGNUM;
787                         FileSpec format_file_spec;
788                         const lldb::RegisterInfo *reg_info = NULL;
789                         RegisterContext *reg_ctx = NULL;
790 
791                         // Each variable must set success to true below...
792                         bool var_success = false;
793                         switch (var_name_begin[0])
794                         {
795                         case 'a':
796                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
797                             {
798                                 if (addr && addr->IsValid())
799                                 {
800                                     var_success = true;
801                                     format_addr = *addr;
802                                 }
803                             }
804                             break;
805 
806                         case 'p':
807                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
808                             {
809                                 if (exe_ctx && exe_ctx->process != NULL)
810                                 {
811                                     var_name_begin += ::strlen ("process.");
812                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
813                                     {
814                                         s.Printf("%i", exe_ctx->process->GetID());
815                                         var_success = true;
816                                     }
817                                     else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
818                                              (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
819                                              (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
820                                     {
821                                         ModuleSP exe_module_sp (exe_ctx->process->GetTarget().GetExecutableModule());
822                                         if (exe_module_sp)
823                                         {
824                                             if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
825                                             {
826                                                 format_file_spec.GetFilename() = exe_module_sp->GetFileSpec().GetFilename();
827                                                 var_success = format_file_spec;
828                                             }
829                                             else
830                                             {
831                                                 format_file_spec = exe_module_sp->GetFileSpec();
832                                                 var_success = format_file_spec;
833                                             }
834                                         }
835                                     }
836                                 }
837                             }
838                             break;
839 
840                         case 't':
841                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
842                             {
843                                 if (exe_ctx && exe_ctx->thread)
844                                 {
845                                     var_name_begin += ::strlen ("thread.");
846                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
847                                     {
848                                         s.Printf("0x%4.4x", exe_ctx->thread->GetID());
849                                         var_success = true;
850                                     }
851                                     else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
852                                     {
853                                         s.Printf("%u", exe_ctx->thread->GetIndexID());
854                                         var_success = true;
855                                     }
856                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
857                                     {
858                                         cstr = exe_ctx->thread->GetName();
859                                         var_success = cstr && cstr[0];
860                                         if (var_success)
861                                             s.PutCString(cstr);
862                                     }
863                                     else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
864                                     {
865                                         cstr = exe_ctx->thread->GetQueueName();
866                                         var_success = cstr && cstr[0];
867                                         if (var_success)
868                                             s.PutCString(cstr);
869                                     }
870                                     else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
871                                     {
872                                         StopInfoSP stop_info_sp = exe_ctx->thread->GetStopInfo ();
873                                         if (stop_info_sp)
874                                         {
875                                             cstr = stop_info_sp->GetDescription();
876                                             if (cstr && cstr[0])
877                                             {
878                                                 s.PutCString(cstr);
879                                                 var_success = true;
880                                             }
881                                         }
882                                     }
883                                 }
884                             }
885                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
886                             {
887                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
888                                 if (target)
889                                 {
890                                     var_name_begin += ::strlen ("target.");
891                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
892                                     {
893                                         ArchSpec arch (target->GetArchitecture ());
894                                         if (arch.IsValid())
895                                         {
896                                             s.PutCString (arch.AsCString());
897                                             var_success = true;
898                                         }
899                                     }
900                                 }
901                             }
902                             break;
903 
904 
905                         case 'm':
906                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
907                             {
908                                 if (sc && sc->module_sp.get())
909                                 {
910                                     Module *module = sc->module_sp.get();
911                                     var_name_begin += ::strlen ("module.");
912 
913                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
914                                     {
915                                         if (module->GetFileSpec())
916                                         {
917                                             var_name_begin += ::strlen ("file.");
918 
919                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
920                                             {
921                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
922                                                 var_success = format_file_spec;
923                                             }
924                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
925                                             {
926                                                 format_file_spec = module->GetFileSpec();
927                                                 var_success = format_file_spec;
928                                             }
929                                         }
930                                     }
931                                 }
932                             }
933                             break;
934 
935 
936                         case 'f':
937                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
938                             {
939                                 if (sc && sc->comp_unit != NULL)
940                                 {
941                                     var_name_begin += ::strlen ("file.");
942 
943                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
944                                     {
945                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
946                                         var_success = format_file_spec;
947                                     }
948                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
949                                     {
950                                         format_file_spec = *sc->comp_unit;
951                                         var_success = format_file_spec;
952                                     }
953                                 }
954                             }
955                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
956                             {
957                                 if (exe_ctx && exe_ctx->frame)
958                                 {
959                                     var_name_begin += ::strlen ("frame.");
960                                     if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
961                                     {
962                                         s.Printf("%u", exe_ctx->frame->GetFrameIndex());
963                                         var_success = true;
964                                     }
965                                     else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
966                                     {
967                                         reg_kind = eRegisterKindGeneric;
968                                         reg_num = LLDB_REGNUM_GENERIC_PC;
969                                         var_success = true;
970                                     }
971                                     else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
972                                     {
973                                         reg_kind = eRegisterKindGeneric;
974                                         reg_num = LLDB_REGNUM_GENERIC_SP;
975                                         var_success = true;
976                                     }
977                                     else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
978                                     {
979                                         reg_kind = eRegisterKindGeneric;
980                                         reg_num = LLDB_REGNUM_GENERIC_FP;
981                                         var_success = true;
982                                     }
983                                     else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
984                                     {
985                                         reg_kind = eRegisterKindGeneric;
986                                         reg_num = LLDB_REGNUM_GENERIC_FLAGS;
987                                         var_success = true;
988                                     }
989                                     else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
990                                     {
991                                         reg_ctx = exe_ctx->frame->GetRegisterContext().get();
992                                         if (reg_ctx)
993                                         {
994                                             var_name_begin += ::strlen ("reg.");
995                                             if (var_name_begin < var_name_end)
996                                             {
997                                                 std::string reg_name (var_name_begin, var_name_end);
998                                                 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
999                                                 if (reg_info)
1000                                                     var_success = true;
1001                                             }
1002                                         }
1003                                     }
1004                                 }
1005                             }
1006                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
1007                             {
1008                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
1009                                 {
1010                                     var_name_begin += ::strlen ("function.");
1011                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
1012                                     {
1013                                         if (sc->function)
1014                                             s.Printf("function{0x%8.8x}", sc->function->GetID());
1015                                         else
1016                                             s.Printf("symbol[%u]", sc->symbol->GetID());
1017 
1018                                         var_success = true;
1019                                     }
1020                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1021                                     {
1022                                         if (sc->function)
1023                                             cstr = sc->function->GetName().AsCString (NULL);
1024                                         else if (sc->symbol)
1025                                             cstr = sc->symbol->GetName().AsCString (NULL);
1026                                         if (cstr)
1027                                         {
1028                                             s.PutCString(cstr);
1029 
1030                                             if (sc->block)
1031                                             {
1032                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1033                                                 if (inline_block)
1034                                                 {
1035                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
1036                                                     if (inline_info)
1037                                                     {
1038                                                         s.PutCString(" [inlined] ");
1039                                                         inline_info->GetName().Dump(&s);
1040                                                     }
1041                                                 }
1042                                             }
1043                                             var_success = true;
1044                                         }
1045                                     }
1046                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
1047                                     {
1048                                         var_success = addr != NULL;
1049                                         if (var_success)
1050                                         {
1051                                             format_addr = *addr;
1052                                             calculate_format_addr_function_offset = true;
1053                                         }
1054                                     }
1055                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
1056                                     {
1057                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
1058                                         if (var_success)
1059                                         {
1060                                             format_addr = sc->line_entry.range.GetBaseAddress();
1061                                             calculate_format_addr_function_offset = true;
1062                                         }
1063                                     }
1064                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
1065                                     {
1066                                         var_success = exe_ctx->frame;
1067                                         if (var_success)
1068                                         {
1069                                             format_addr = exe_ctx->frame->GetFrameCodeAddress();
1070                                             calculate_format_addr_function_offset = true;
1071                                         }
1072                                     }
1073                                 }
1074                             }
1075                             break;
1076 
1077                         case 'l':
1078                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
1079                             {
1080                                 if (sc && sc->line_entry.IsValid())
1081                                 {
1082                                     var_name_begin += ::strlen ("line.");
1083                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1084                                     {
1085                                         var_name_begin += ::strlen ("file.");
1086 
1087                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1088                                         {
1089                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
1090                                             var_success = format_file_spec;
1091                                         }
1092                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1093                                         {
1094                                             format_file_spec = sc->line_entry.file;
1095                                             var_success = format_file_spec;
1096                                         }
1097                                     }
1098                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
1099                                     {
1100                                         var_success = true;
1101                                         s.Printf("%u", sc->line_entry.line);
1102                                     }
1103                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
1104                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
1105                                     {
1106                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
1107                                         if (var_success)
1108                                         {
1109                                             format_addr = sc->line_entry.range.GetBaseAddress();
1110                                             if (var_name_begin[0] == 'e')
1111                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
1112                                         }
1113                                     }
1114                                 }
1115                             }
1116                             break;
1117                         }
1118 
1119                         if (var_success)
1120                         {
1121                             // If format addr is valid, then we need to print an address
1122                             if (reg_num != LLDB_INVALID_REGNUM)
1123                             {
1124                                 // We have a register value to display...
1125                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
1126                                 {
1127                                     format_addr = exe_ctx->frame->GetFrameCodeAddress();
1128                                 }
1129                                 else
1130                                 {
1131                                     if (reg_ctx == NULL)
1132                                         reg_ctx = exe_ctx->frame->GetRegisterContext().get();
1133 
1134                                     if (reg_ctx)
1135                                     {
1136                                         if (reg_kind != kNumRegisterKinds)
1137                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
1138                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
1139                                         var_success = reg_info != NULL;
1140                                     }
1141                                 }
1142                             }
1143 
1144                             if (reg_info != NULL)
1145                             {
1146                                 DataExtractor reg_data;
1147                                 var_success = reg_ctx->ReadRegisterBytes (reg_info->kinds[eRegisterKindLLDB], reg_data);
1148                                 {
1149                                     reg_data.Dump(&s, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
1150                                 }
1151                             }
1152 
1153                             if (format_file_spec)
1154                             {
1155                                 s << format_file_spec;
1156                             }
1157 
1158                             // If format addr is valid, then we need to print an address
1159                             if (format_addr.IsValid())
1160                             {
1161                                 var_success = false;
1162 
1163                                 if (calculate_format_addr_function_offset)
1164                                 {
1165                                     Address func_addr;
1166 
1167                                     if (sc)
1168                                     {
1169                                         if (sc->function)
1170                                         {
1171                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
1172                                             if (sc->block)
1173                                             {
1174                                                 // Check to make sure we aren't in an inline
1175                                                 // function. If we are, use the inline block
1176                                                 // range that contains "format_addr" since
1177                                                 // blocks can be discontiguous.
1178                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1179                                                 AddressRange inline_range;
1180                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
1181                                                     func_addr = inline_range.GetBaseAddress();
1182                                             }
1183                                         }
1184                                         else if (sc->symbol && sc->symbol->GetAddressRangePtr())
1185                                             func_addr = sc->symbol->GetAddressRangePtr()->GetBaseAddress();
1186                                     }
1187 
1188                                     if (func_addr.IsValid())
1189                                     {
1190                                         if (func_addr.GetSection() == format_addr.GetSection())
1191                                         {
1192                                             addr_t func_file_addr = func_addr.GetFileAddress();
1193                                             addr_t addr_file_addr = format_addr.GetFileAddress();
1194                                             if (addr_file_addr > func_file_addr)
1195                                                 s.Printf(" + %llu", addr_file_addr - func_file_addr);
1196                                             else if (addr_file_addr < func_file_addr)
1197                                                 s.Printf(" - %llu", func_file_addr - addr_file_addr);
1198                                             var_success = true;
1199                                         }
1200                                         else
1201                                         {
1202                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1203                                             if (target)
1204                                             {
1205                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
1206                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
1207                                                 if (addr_load_addr > func_load_addr)
1208                                                     s.Printf(" + %llu", addr_load_addr - func_load_addr);
1209                                                 else if (addr_load_addr < func_load_addr)
1210                                                     s.Printf(" - %llu", func_load_addr - addr_load_addr);
1211                                                 var_success = true;
1212                                             }
1213                                         }
1214                                     }
1215                                 }
1216                                 else
1217                                 {
1218                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1219                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
1220                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
1221                                         vaddr = format_addr.GetLoadAddress (target);
1222                                     if (vaddr == LLDB_INVALID_ADDRESS)
1223                                         vaddr = format_addr.GetFileAddress ();
1224 
1225                                     if (vaddr != LLDB_INVALID_ADDRESS)
1226                                     {
1227                                         int addr_width = 0;
1228                                         if (exe_ctx && exe_ctx->process)
1229                                             addr_width = exe_ctx->process->GetAddressByteSize() * 2;
1230                                         if (addr_width == 0)
1231                                             addr_width = 16;
1232                                         s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
1233                                         var_success = true;
1234                                     }
1235                                 }
1236                             }
1237                         }
1238 
1239                         if (var_success == false)
1240                             success = false;
1241                     }
1242                     p = var_name_end;
1243                 }
1244                 else
1245                     break;
1246             }
1247             else
1248             {
1249                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
1250                 s.PutChar(*p);
1251             }
1252         }
1253         else if (*p == '\\')
1254         {
1255             ++p; // skip the slash
1256             switch (*p)
1257             {
1258             case 'a': s.PutChar ('\a'); break;
1259             case 'b': s.PutChar ('\b'); break;
1260             case 'f': s.PutChar ('\f'); break;
1261             case 'n': s.PutChar ('\n'); break;
1262             case 'r': s.PutChar ('\r'); break;
1263             case 't': s.PutChar ('\t'); break;
1264             case 'v': s.PutChar ('\v'); break;
1265             case '\'': s.PutChar ('\''); break;
1266             case '\\': s.PutChar ('\\'); break;
1267             case '0':
1268                 // 1 to 3 octal chars
1269                 {
1270                     // Make a string that can hold onto the initial zero char,
1271                     // up to 3 octal digits, and a terminating NULL.
1272                     char oct_str[5] = { 0, 0, 0, 0, 0 };
1273 
1274                     int i;
1275                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
1276                         oct_str[i] = p[i];
1277 
1278                     // We don't want to consume the last octal character since
1279                     // the main for loop will do this for us, so we advance p by
1280                     // one less than i (even if i is zero)
1281                     p += i - 1;
1282                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
1283                     if (octal_value <= UINT8_MAX)
1284                     {
1285                         char octal_char = octal_value;
1286                         s.Write (&octal_char, 1);
1287                     }
1288                 }
1289                 break;
1290 
1291             case 'x':
1292                 // hex number in the format
1293                 if (isxdigit(p[1]))
1294                 {
1295                     ++p;    // Skip the 'x'
1296 
1297                     // Make a string that can hold onto two hex chars plus a
1298                     // NULL terminator
1299                     char hex_str[3] = { 0,0,0 };
1300                     hex_str[0] = *p;
1301                     if (isxdigit(p[1]))
1302                     {
1303                         ++p; // Skip the first of the two hex chars
1304                         hex_str[1] = *p;
1305                     }
1306 
1307                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
1308                     if (hex_value <= UINT8_MAX)
1309                         s.PutChar (hex_value);
1310                 }
1311                 else
1312                 {
1313                     s.PutChar('x');
1314                 }
1315                 break;
1316 
1317             default:
1318                 // Just desensitize any other character by just printing what
1319                 // came after the '\'
1320                 s << *p;
1321                 break;
1322 
1323             }
1324 
1325         }
1326     }
1327     if (end)
1328         *end = p;
1329     return success;
1330 }
1331 
1332 #pragma mark Debugger::SettingsController
1333 
1334 //--------------------------------------------------
1335 // class Debugger::SettingsController
1336 //--------------------------------------------------
1337 
1338 Debugger::SettingsController::SettingsController () :
1339     UserSettingsController ("", lldb::UserSettingsControllerSP())
1340 {
1341     m_default_settings.reset (new DebuggerInstanceSettings (*this, false,
1342                                                             InstanceSettings::GetDefaultName().AsCString()));
1343 }
1344 
1345 Debugger::SettingsController::~SettingsController ()
1346 {
1347 }
1348 
1349 
1350 lldb::InstanceSettingsSP
1351 Debugger::SettingsController::CreateInstanceSettings (const char *instance_name)
1352 {
1353     DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*GetSettingsController(),
1354                                                                            false, instance_name);
1355     lldb::InstanceSettingsSP new_settings_sp (new_settings);
1356     return new_settings_sp;
1357 }
1358 
1359 #pragma mark DebuggerInstanceSettings
1360 //--------------------------------------------------
1361 //  class DebuggerInstanceSettings
1362 //--------------------------------------------------
1363 
1364 DebuggerInstanceSettings::DebuggerInstanceSettings
1365 (
1366     UserSettingsController &owner,
1367     bool live_instance,
1368     const char *name
1369 ) :
1370     InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
1371     m_term_width (80),
1372     m_prompt (),
1373     m_frame_format (),
1374     m_thread_format (),
1375     m_script_lang (),
1376     m_use_external_editor (false),
1377     m_auto_confirm_on (false)
1378 {
1379     // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
1380     // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers.
1381     // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
1382     // The same is true of CreateInstanceName().
1383 
1384     if (GetInstanceName() == InstanceSettings::InvalidName())
1385     {
1386         ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
1387         m_owner.RegisterInstanceSettings (this);
1388     }
1389 
1390     if (live_instance)
1391     {
1392         const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1393         CopyInstanceSettings (pending_settings, false);
1394     }
1395 }
1396 
1397 DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
1398     InstanceSettings (*Debugger::GetSettingsController(), CreateInstanceName ().AsCString()),
1399     m_prompt (rhs.m_prompt),
1400     m_frame_format (rhs.m_frame_format),
1401     m_thread_format (rhs.m_thread_format),
1402     m_script_lang (rhs.m_script_lang),
1403     m_use_external_editor (rhs.m_use_external_editor),
1404     m_auto_confirm_on(rhs.m_auto_confirm_on)
1405 {
1406     const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1407     CopyInstanceSettings (pending_settings, false);
1408     m_owner.RemovePendingSettings (m_instance_name);
1409 }
1410 
1411 DebuggerInstanceSettings::~DebuggerInstanceSettings ()
1412 {
1413 }
1414 
1415 DebuggerInstanceSettings&
1416 DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
1417 {
1418     if (this != &rhs)
1419     {
1420         m_term_width = rhs.m_term_width;
1421         m_prompt = rhs.m_prompt;
1422         m_frame_format = rhs.m_frame_format;
1423         m_thread_format = rhs.m_thread_format;
1424         m_script_lang = rhs.m_script_lang;
1425         m_use_external_editor = rhs.m_use_external_editor;
1426         m_auto_confirm_on = rhs.m_auto_confirm_on;
1427     }
1428 
1429     return *this;
1430 }
1431 
1432 bool
1433 DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err)
1434 {
1435     bool valid = false;
1436 
1437     // Verify we have a value string.
1438     if (value == NULL || value[0] == '\0')
1439     {
1440         err.SetErrorString ("Missing value. Can't set terminal width without a value.\n");
1441     }
1442     else
1443     {
1444         char *end = NULL;
1445         const uint32_t width = ::strtoul (value, &end, 0);
1446 
1447         if (end && end[0] == '\0')
1448         {
1449             if (width >= 10 && width <= 1024)
1450                 valid = true;
1451             else
1452                 err.SetErrorString ("Invalid term-width value; value must be between 10 and 1024.\n");
1453         }
1454         else
1455             err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string.\n", value);
1456     }
1457 
1458     return valid;
1459 }
1460 
1461 
1462 void
1463 DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1464                                                           const char *index_value,
1465                                                           const char *value,
1466                                                           const ConstString &instance_name,
1467                                                           const SettingEntry &entry,
1468                                                           lldb::VarSetOperationType op,
1469                                                           Error &err,
1470                                                           bool pending)
1471 {
1472 
1473     if (var_name == TermWidthVarName())
1474     {
1475         if (ValidTermWidthValue (value, err))
1476         {
1477             m_term_width = ::strtoul (value, NULL, 0);
1478         }
1479     }
1480     else if (var_name == PromptVarName())
1481     {
1482         UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
1483         if (!pending)
1484         {
1485             // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
1486             // strip off the brackets before passing it to BroadcastPromptChange.
1487 
1488             std::string tmp_instance_name (instance_name.AsCString());
1489             if ((tmp_instance_name[0] == '[')
1490                 && (tmp_instance_name[instance_name.GetLength() - 1] == ']'))
1491                 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2);
1492             ConstString new_name (tmp_instance_name.c_str());
1493 
1494             BroadcastPromptChange (new_name, m_prompt.c_str());
1495         }
1496     }
1497     else if (var_name == GetFrameFormatName())
1498     {
1499         UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err);
1500     }
1501     else if (var_name == GetThreadFormatName())
1502     {
1503         UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err);
1504     }
1505     else if (var_name == ScriptLangVarName())
1506     {
1507         bool success;
1508         m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
1509                                                       &success);
1510     }
1511     else if (var_name == UseExternalEditorVarName ())
1512     {
1513         UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, err);
1514     }
1515     else if (var_name == AutoConfirmName ())
1516     {
1517         UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, err);
1518     }
1519 }
1520 
1521 bool
1522 DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
1523                                                     const ConstString &var_name,
1524                                                     StringList &value,
1525                                                     Error *err)
1526 {
1527     if (var_name == PromptVarName())
1528     {
1529         value.AppendString (m_prompt.c_str(), m_prompt.size());
1530 
1531     }
1532     else if (var_name == ScriptLangVarName())
1533     {
1534         value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
1535     }
1536     else if (var_name == TermWidthVarName())
1537     {
1538         StreamString width_str;
1539         width_str.Printf ("%d", m_term_width);
1540         value.AppendString (width_str.GetData());
1541     }
1542     else if (var_name == GetFrameFormatName ())
1543     {
1544         value.AppendString(m_frame_format.c_str(), m_frame_format.size());
1545     }
1546     else if (var_name == GetThreadFormatName ())
1547     {
1548         value.AppendString(m_thread_format.c_str(), m_thread_format.size());
1549     }
1550     else if (var_name == UseExternalEditorVarName())
1551     {
1552         if (m_use_external_editor)
1553             value.AppendString ("true");
1554         else
1555             value.AppendString ("false");
1556     }
1557     else if (var_name == AutoConfirmName())
1558     {
1559         if (m_auto_confirm_on)
1560             value.AppendString ("true");
1561         else
1562             value.AppendString ("false");
1563     }
1564     else
1565     {
1566         if (err)
1567             err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
1568         return false;
1569     }
1570     return true;
1571 }
1572 
1573 void
1574 DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
1575                                                 bool pending)
1576 {
1577     if (new_settings.get() == NULL)
1578         return;
1579 
1580     DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
1581 
1582     m_prompt = new_debugger_settings->m_prompt;
1583     if (!pending)
1584     {
1585         // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
1586         // strip off the brackets before passing it to BroadcastPromptChange.
1587 
1588         std::string tmp_instance_name (m_instance_name.AsCString());
1589         if ((tmp_instance_name[0] == '[')
1590             && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']'))
1591             tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2);
1592         ConstString new_name (tmp_instance_name.c_str());
1593 
1594         BroadcastPromptChange (new_name, m_prompt.c_str());
1595     }
1596     m_frame_format = new_debugger_settings->m_frame_format;
1597     m_thread_format = new_debugger_settings->m_thread_format;
1598     m_term_width = new_debugger_settings->m_term_width;
1599     m_script_lang = new_debugger_settings->m_script_lang;
1600     m_use_external_editor = new_debugger_settings->m_use_external_editor;
1601     m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on;
1602 }
1603 
1604 
1605 bool
1606 DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
1607 {
1608     std::string tmp_prompt;
1609 
1610     if (new_prompt != NULL)
1611     {
1612         tmp_prompt = new_prompt ;
1613         int len = tmp_prompt.size();
1614         if (len > 1
1615             && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
1616             && (tmp_prompt[len-1] == tmp_prompt[0]))
1617         {
1618             tmp_prompt = tmp_prompt.substr(1,len-2);
1619         }
1620         len = tmp_prompt.size();
1621         if (tmp_prompt[len-1] != ' ')
1622             tmp_prompt.append(" ");
1623     }
1624     EventSP new_event_sp;
1625     new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
1626                                   new EventDataBytes (tmp_prompt.c_str())));
1627 
1628     if (instance_name.GetLength() != 0)
1629     {
1630         // Set prompt for a particular instance.
1631         Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
1632         if (dbg != NULL)
1633         {
1634             dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
1635         }
1636     }
1637 
1638     return true;
1639 }
1640 
1641 const ConstString
1642 DebuggerInstanceSettings::CreateInstanceName ()
1643 {
1644     static int instance_count = 1;
1645     StreamString sstr;
1646 
1647     sstr.Printf ("debugger_%d", instance_count);
1648     ++instance_count;
1649 
1650     const ConstString ret_val (sstr.GetData());
1651 
1652     return ret_val;
1653 }
1654 
1655 const ConstString &
1656 DebuggerInstanceSettings::PromptVarName ()
1657 {
1658     static ConstString prompt_var_name ("prompt");
1659 
1660     return prompt_var_name;
1661 }
1662 
1663 const ConstString &
1664 DebuggerInstanceSettings::GetFrameFormatName ()
1665 {
1666     static ConstString prompt_var_name ("frame-format");
1667 
1668     return prompt_var_name;
1669 }
1670 
1671 const ConstString &
1672 DebuggerInstanceSettings::GetThreadFormatName ()
1673 {
1674     static ConstString prompt_var_name ("thread-format");
1675 
1676     return prompt_var_name;
1677 }
1678 
1679 const ConstString &
1680 DebuggerInstanceSettings::ScriptLangVarName ()
1681 {
1682     static ConstString script_lang_var_name ("script-lang");
1683 
1684     return script_lang_var_name;
1685 }
1686 
1687 const ConstString &
1688 DebuggerInstanceSettings::TermWidthVarName ()
1689 {
1690     static ConstString term_width_var_name ("term-width");
1691 
1692     return term_width_var_name;
1693 }
1694 
1695 const ConstString &
1696 DebuggerInstanceSettings::UseExternalEditorVarName ()
1697 {
1698     static ConstString use_external_editor_var_name ("use-external-editor");
1699 
1700     return use_external_editor_var_name;
1701 }
1702 
1703 const ConstString &
1704 DebuggerInstanceSettings::AutoConfirmName ()
1705 {
1706     static ConstString use_external_editor_var_name ("auto-confirm");
1707 
1708     return use_external_editor_var_name;
1709 }
1710 
1711 //--------------------------------------------------
1712 // SettingsController Variable Tables
1713 //--------------------------------------------------
1714 
1715 
1716 SettingEntry
1717 Debugger::SettingsController::global_settings_table[] =
1718 {
1719   //{ "var-name",    var-type,      "default", enum-table, init'd, hidden, "help-text"},
1720   // The Debugger level global table should always be empty; all Debugger settable variables should be instance
1721   // variables.
1722     {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1723 };
1724 
1725 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}"
1726 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
1727 
1728 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1729     "{, ${frame.pc}}"\
1730     MODULE_WITH_FUNC\
1731     FILE_AND_LINE\
1732     "{, stop reason = ${thread.stop-reason}}"\
1733     "\\n"
1734 
1735 //#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1736 //    "{, ${frame.pc}}"\
1737 //    MODULE_WITH_FUNC\
1738 //    FILE_AND_LINE\
1739 //    "{, stop reason = ${thread.stop-reason}}"\
1740 //    "{, name = ${thread.name}}"\
1741 //    "{, queue = ${thread.queue}}"\
1742 //    "\\n"
1743 
1744 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
1745     MODULE_WITH_FUNC\
1746     FILE_AND_LINE\
1747     "\\n"
1748 
1749 SettingEntry
1750 Debugger::SettingsController::instance_settings_table[] =
1751 {
1752 //  NAME                    Setting variable type   Default                 Enum  Init'd Hidden Help
1753 //  ======================= ======================= ======================  ====  ====== ====== ======================
1754 {   "frame-format",         eSetVarTypeString,      DEFAULT_FRAME_FORMAT,   NULL, false, false, "The default frame format string to use when displaying thread information." },
1755 {   "prompt",               eSetVarTypeString,      "(lldb) ",              NULL, false, false, "The debugger command line prompt displayed for the user." },
1756 {   "script-lang",          eSetVarTypeString,      "python",               NULL, false, false, "The script language to be used for evaluating user-written scripts." },
1757 {   "term-width",           eSetVarTypeInt,         "80"    ,               NULL, false, false, "The maximum number of columns to use for displaying text." },
1758 {   "thread-format",        eSetVarTypeString,      DEFAULT_THREAD_FORMAT,  NULL, false, false, "The default thread format string to use when displaying thread information." },
1759 {   "use-external-editor",  eSetVarTypeBoolean,        "false",                NULL, false, false, "Whether to use an external editor or not." },
1760 {   "auto-confirm",         eSetVarTypeBoolean,        "false",                NULL, false, false, "If true all confirmation prompts will receive their default reply." },
1761 {   NULL,                   eSetVarTypeNone,        NULL,                   NULL, false, false, NULL }
1762 };
1763