1 //===-- SBCommandInterpreter.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-types.h"
11 #include "lldb/Interpreter/Args.h"
12 #include "lldb/Core/SourceManager.h"
13 #include "lldb/Core/Listener.h"
14 #include "lldb/Interpreter/CommandInterpreter.h"
15 #include "lldb/Interpreter/CommandReturnObject.h"
16 #include "lldb/Target/Target.h"
17 
18 #include "lldb/API/SBBroadcaster.h"
19 #include "lldb/API/SBDebugger.h"
20 #include "lldb/API/SBCommandReturnObject.h"
21 #include "lldb/API/SBSourceManager.h"
22 #include "lldb/API/SBCommandInterpreter.h"
23 #include "lldb/API/SBProcess.h"
24 #include "lldb/API/SBTarget.h"
25 #include "lldb/API/SBListener.h"
26 #include "lldb/API/SBStream.h"
27 #include "lldb/API/SBStringList.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 
33 SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) :
34     m_opaque_ptr (interpreter)
35 {
36     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
37 
38     if (log)
39         log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)"
40                      " => SBCommandInterpreter(%p)", interpreter, m_opaque_ptr);
41 }
42 
43 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) :
44     m_opaque_ptr (rhs.m_opaque_ptr)
45 {
46 }
47 
48 const SBCommandInterpreter &
49 SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs)
50 {
51     m_opaque_ptr = rhs.m_opaque_ptr;
52     return *this;
53 }
54 
55 SBCommandInterpreter::~SBCommandInterpreter ()
56 {
57 }
58 
59 bool
60 SBCommandInterpreter::IsValid() const
61 {
62     return m_opaque_ptr != NULL;
63 }
64 
65 
66 bool
67 SBCommandInterpreter::CommandExists (const char *cmd)
68 {
69     if (m_opaque_ptr)
70         return m_opaque_ptr->CommandExists (cmd);
71     return false;
72 }
73 
74 bool
75 SBCommandInterpreter::AliasExists (const char *cmd)
76 {
77     if (m_opaque_ptr)
78         return m_opaque_ptr->AliasExists (cmd);
79     return false;
80 }
81 
82 lldb::ReturnStatus
83 SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history)
84 {
85     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
86 
87     if (log)
88         log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)",
89                      m_opaque_ptr, command_line, result.get(), add_to_history);
90 
91     result.Clear();
92     if (m_opaque_ptr)
93     {
94         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
95         Mutex::Locker api_locker;
96         if (target_sp)
97             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
98         m_opaque_ptr->HandleCommand (command_line, add_to_history, result.ref());
99     }
100     else
101     {
102         result->AppendError ("SBCommandInterpreter is not valid");
103         result->SetStatus (eReturnStatusFailed);
104     }
105 
106     // We need to get the value again, in case the command disabled the log!
107     log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
108     if (log)
109     {
110         SBStream sstr;
111         result.GetDescription (sstr);
112         log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i",
113                      m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus());
114     }
115 
116     return result.GetStatus();
117 }
118 
119 int
120 SBCommandInterpreter::HandleCompletion (const char *current_line,
121                                         const char *cursor,
122                                         const char *last_char,
123                                         int match_start_point,
124                                         int max_return_elements,
125                                         SBStringList &matches)
126 {
127     int num_completions = 0;
128     if (m_opaque_ptr)
129     {
130         lldb_private::StringList lldb_matches;
131         num_completions =  m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point,
132                                                            max_return_elements, lldb_matches);
133 
134         SBStringList temp_list (&lldb_matches);
135         matches.AppendList (temp_list);
136     }
137     return num_completions;
138 }
139 
140 bool
141 SBCommandInterpreter::HasCommands ()
142 {
143     if (m_opaque_ptr)
144         return m_opaque_ptr->HasCommands();
145     return false;
146 }
147 
148 bool
149 SBCommandInterpreter::HasAliases ()
150 {
151     if (m_opaque_ptr)
152         return m_opaque_ptr->HasAliases();
153     return false;
154 }
155 
156 bool
157 SBCommandInterpreter::HasAliasOptions ()
158 {
159     if (m_opaque_ptr)
160         return m_opaque_ptr->HasAliasOptions ();
161     return false;
162 }
163 
164 SBProcess
165 SBCommandInterpreter::GetProcess ()
166 {
167     SBProcess process;
168     if (m_opaque_ptr)
169     {
170         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
171         if (target_sp)
172         {
173             Mutex::Locker api_locker(target_sp->GetAPIMutex());
174             process.SetProcess(target_sp->GetProcessSP());
175         }
176     }
177     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
178 
179     if (log)
180         log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)",
181                      m_opaque_ptr, process.get());
182 
183 
184     return process;
185 }
186 
187 ssize_t
188 SBCommandInterpreter::WriteToScriptInterpreter (const char *src)
189 {
190     return WriteToScriptInterpreter (src, strlen(src));
191 }
192 
193 ssize_t
194 SBCommandInterpreter::WriteToScriptInterpreter (const char *src, size_t src_len)
195 {
196     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
197 
198     ssize_t bytes_written = 0;
199     if (m_opaque_ptr && src && src[0])
200     {
201         ScriptInterpreter *script_interpreter = m_opaque_ptr->GetScriptInterpreter();
202         if (script_interpreter)
203             bytes_written = ::write (script_interpreter->GetMasterFileDescriptor(), src, src_len);
204     }
205     if (log)
206         log->Printf ("SBCommandInterpreter(%p)::WriteToScriptInterpreter (src=\"%s\", src_len=%zu) => %zi",
207                      m_opaque_ptr, src, src_len, bytes_written);
208 
209     return bytes_written;
210 }
211 
212 
213 CommandInterpreter *
214 SBCommandInterpreter::get ()
215 {
216     return m_opaque_ptr;
217 }
218 
219 CommandInterpreter &
220 SBCommandInterpreter::ref ()
221 {
222     assert (m_opaque_ptr);
223     return *m_opaque_ptr;
224 }
225 
226 void
227 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter)
228 {
229     m_opaque_ptr = interpreter;
230 }
231 
232 void
233 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result)
234 {
235     result.Clear();
236     if (m_opaque_ptr)
237     {
238         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
239         Mutex::Locker api_locker;
240         if (target_sp)
241             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
242         m_opaque_ptr->SourceInitFile (false, result.ref());
243     }
244     else
245     {
246         result->AppendError ("SBCommandInterpreter is not valid");
247         result->SetStatus (eReturnStatusFailed);
248     }
249     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
250 
251     if (log)
252         log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))",
253                      m_opaque_ptr, result.get());
254 
255 }
256 
257 void
258 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result)
259 {
260     result.Clear();
261     if (m_opaque_ptr)
262     {
263         TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
264         Mutex::Locker api_locker;
265         if (target_sp)
266             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
267         m_opaque_ptr->SourceInitFile (true, result.ref());
268     }
269     else
270     {
271         result->AppendError ("SBCommandInterpreter is not valid");
272         result->SetStatus (eReturnStatusFailed);
273     }
274     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
275 
276     if (log)
277         log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))",
278                      m_opaque_ptr, result.get());
279 }
280 
281 SBBroadcaster
282 SBCommandInterpreter::GetBroadcaster ()
283 {
284     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
285 
286     SBBroadcaster broadcaster (m_opaque_ptr, false);
287 
288     if (log)
289         log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)",
290                      m_opaque_ptr, broadcaster.get());
291 
292     return broadcaster;
293 }
294 
295 const char *
296 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
297 {
298     return CommandObject::GetArgumentTypeAsCString (arg_type);
299 }
300 
301 const char *
302 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
303 {
304     return CommandObject::GetArgumentDescriptionAsCString (arg_type);
305 }
306 
307 
308 extern "C" bool
309 LLDBSwigPythonBreakpointCallbackFunction
310 (
311     const char *python_function_name,
312     const char *session_dictionary_name,
313     const lldb::StackFrameSP& sb_frame,
314     const lldb::BreakpointLocationSP& sb_bp_loc
315 );
316 
317 extern "C" void init_lldb(void);
318 
319 void
320 SBCommandInterpreter::InitializeSWIG ()
321 {
322     static bool g_initialized = false;
323     if (!g_initialized)
324     {
325         g_initialized = true;
326         ScriptInterpreter::InitializeInterpreter (init_lldb,
327                                                   LLDBSwigPythonBreakpointCallbackFunction);
328     }
329 }
330