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