SBCommandInterpreter.cpp revision 3e4238d47a6d1a3106f357d2e7b495870721c7ae
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/SBCommandInterpreter.h"
22#include "lldb/API/SBProcess.h"
23#include "lldb/API/SBTarget.h"
24#include "lldb/API/SBListener.h"
25#include "lldb/API/SBStream.h"
26#include "lldb/API/SBStringList.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31
32SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) :
33    m_opaque_ptr (interpreter)
34{
35    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
36
37    if (log)
38        log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)"
39                     " => SBCommandInterpreter(%p)", interpreter, m_opaque_ptr);
40}
41
42SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) :
43    m_opaque_ptr (rhs.m_opaque_ptr)
44{
45}
46
47const SBCommandInterpreter &
48SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs)
49{
50    m_opaque_ptr = rhs.m_opaque_ptr;
51    return *this;
52}
53
54SBCommandInterpreter::~SBCommandInterpreter ()
55{
56}
57
58bool
59SBCommandInterpreter::IsValid() const
60{
61    return m_opaque_ptr != NULL;
62}
63
64
65bool
66SBCommandInterpreter::CommandExists (const char *cmd)
67{
68    if (m_opaque_ptr)
69        return m_opaque_ptr->CommandExists (cmd);
70    return false;
71}
72
73bool
74SBCommandInterpreter::AliasExists (const char *cmd)
75{
76    if (m_opaque_ptr)
77        return m_opaque_ptr->AliasExists (cmd);
78    return false;
79}
80
81lldb::ReturnStatus
82SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history)
83{
84    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
85
86    if (log)
87        log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)",
88                     m_opaque_ptr, command_line, result.get(), add_to_history);
89
90    result.Clear();
91    if (m_opaque_ptr)
92    {
93        TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
94        Mutex::Locker api_locker;
95        if (target_sp)
96            api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
97        m_opaque_ptr->HandleCommand (command_line, add_to_history, result.ref());
98    }
99    else
100    {
101        result->AppendError ("SBCommandInterpreter is not valid");
102        result->SetStatus (eReturnStatusFailed);
103    }
104
105    // We need to get the value again, in case the command disabled the log!
106    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
107    if (log)
108    {
109        SBStream sstr;
110        result.GetDescription (sstr);
111        log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i",
112                     m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus());
113    }
114
115    return result.GetStatus();
116}
117
118int
119SBCommandInterpreter::HandleCompletion (const char *current_line,
120                                        const char *cursor,
121                                        const char *last_char,
122                                        int match_start_point,
123                                        int max_return_elements,
124                                        SBStringList &matches)
125{
126    int num_completions = 0;
127    if (m_opaque_ptr)
128    {
129        lldb_private::StringList lldb_matches;
130        num_completions =  m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point,
131                                                           max_return_elements, lldb_matches);
132
133        SBStringList temp_list (&lldb_matches);
134        matches.AppendList (temp_list);
135    }
136    return num_completions;
137}
138
139int
140SBCommandInterpreter::HandleCompletion (const char *current_line,
141                  uint32_t cursor_pos,
142                  int match_start_point,
143                  int max_return_elements,
144                  lldb::SBStringList &matches)
145{
146    const char *cursor = current_line + cursor_pos;
147    const char *last_char = current_line + strlen (current_line);
148    return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches);
149}
150
151bool
152SBCommandInterpreter::HasCommands ()
153{
154    if (m_opaque_ptr)
155        return m_opaque_ptr->HasCommands();
156    return false;
157}
158
159bool
160SBCommandInterpreter::HasAliases ()
161{
162    if (m_opaque_ptr)
163        return m_opaque_ptr->HasAliases();
164    return false;
165}
166
167bool
168SBCommandInterpreter::HasAliasOptions ()
169{
170    if (m_opaque_ptr)
171        return m_opaque_ptr->HasAliasOptions ();
172    return false;
173}
174
175SBProcess
176SBCommandInterpreter::GetProcess ()
177{
178    SBProcess process;
179    if (m_opaque_ptr)
180    {
181        TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
182        if (target_sp)
183        {
184            Mutex::Locker api_locker(target_sp->GetAPIMutex());
185            process.SetProcess(target_sp->GetProcessSP());
186        }
187    }
188    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
189
190    if (log)
191        log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)",
192                     m_opaque_ptr, process.get());
193
194
195    return process;
196}
197
198ssize_t
199SBCommandInterpreter::WriteToScriptInterpreter (const char *src)
200{
201    return WriteToScriptInterpreter (src, strlen(src));
202}
203
204ssize_t
205SBCommandInterpreter::WriteToScriptInterpreter (const char *src, size_t src_len)
206{
207    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
208
209    ssize_t bytes_written = 0;
210    if (m_opaque_ptr && src && src[0])
211    {
212        ScriptInterpreter *script_interpreter = m_opaque_ptr->GetScriptInterpreter();
213        if (script_interpreter)
214            bytes_written = ::write (script_interpreter->GetMasterFileDescriptor(), src, src_len);
215    }
216    if (log)
217        log->Printf ("SBCommandInterpreter(%p)::WriteToScriptInterpreter (src=\"%s\", src_len=%zu) => %zi",
218                     m_opaque_ptr, src, src_len, bytes_written);
219
220    return bytes_written;
221}
222
223
224CommandInterpreter *
225SBCommandInterpreter::get ()
226{
227    return m_opaque_ptr;
228}
229
230CommandInterpreter &
231SBCommandInterpreter::ref ()
232{
233    assert (m_opaque_ptr);
234    return *m_opaque_ptr;
235}
236
237void
238SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter)
239{
240    m_opaque_ptr = interpreter;
241}
242
243void
244SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result)
245{
246    result.Clear();
247    if (m_opaque_ptr)
248    {
249        TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
250        Mutex::Locker api_locker;
251        if (target_sp)
252            api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
253        m_opaque_ptr->SourceInitFile (false, result.ref());
254    }
255    else
256    {
257        result->AppendError ("SBCommandInterpreter is not valid");
258        result->SetStatus (eReturnStatusFailed);
259    }
260    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
261
262    if (log)
263        log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))",
264                     m_opaque_ptr, result.get());
265
266}
267
268void
269SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result)
270{
271    result.Clear();
272    if (m_opaque_ptr)
273    {
274        TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
275        Mutex::Locker api_locker;
276        if (target_sp)
277            api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
278        m_opaque_ptr->SourceInitFile (true, result.ref());
279    }
280    else
281    {
282        result->AppendError ("SBCommandInterpreter is not valid");
283        result->SetStatus (eReturnStatusFailed);
284    }
285    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
286
287    if (log)
288        log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))",
289                     m_opaque_ptr, result.get());
290}
291
292SBBroadcaster
293SBCommandInterpreter::GetBroadcaster ()
294{
295    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
296
297    SBBroadcaster broadcaster (m_opaque_ptr, false);
298
299    if (log)
300        log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)",
301                     m_opaque_ptr, broadcaster.get());
302
303    return broadcaster;
304}
305
306const char *
307SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
308{
309    return CommandObject::GetArgumentTypeAsCString (arg_type);
310}
311
312const char *
313SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
314{
315    return CommandObject::GetArgumentDescriptionAsCString (arg_type);
316}
317
318
319#ifndef LLDB_DISABLE_PYTHON
320extern "C" bool
321LLDBSwigPythonBreakpointCallbackFunction
322(
323    const char *python_function_name,
324    const char *session_dictionary_name,
325    const lldb::StackFrameSP& sb_frame,
326    const lldb::BreakpointLocationSP& sb_bp_loc
327);
328
329extern "C" std::string
330LLDBSwigPythonCallTypeScript
331(
332    const char *python_function_name,
333    const char *session_dictionary_name,
334    const lldb::ValueObjectSP& valobj_sp
335);
336
337extern "C" void*
338LLDBSwigPythonCreateSyntheticProvider
339(
340    const std::string python_class_name,
341    const char *session_dictionary_name,
342    const lldb::ValueObjectSP& valobj_sp
343);
344
345
346extern "C" uint32_t       LLDBSwigPython_CalculateNumChildren        (void *implementor);
347extern "C" void*          LLDBSwigPython_GetChildAtIndex             (void *implementor, uint32_t idx);
348extern "C" int            LLDBSwigPython_GetIndexOfChildWithName     (void *implementor, const char* child_name);
349extern "C" void*          LLDBSWIGPython_CastPyObjectToSBValue       (void* data);
350extern "C" void           LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
351
352extern "C" bool           LLDBSwigPythonCallCommand
353(
354    const char *python_function_name,
355    const char *session_dictionary_name,
356    lldb::DebuggerSP& debugger,
357    const char* args,
358    std::string& err_msg,
359    lldb_private::CommandReturnObject& cmd_retobj
360);
361
362// Defined in the SWIG source file
363extern "C" void
364init_lldb(void);
365
366extern "C" bool           LLDBSwigPythonCallModuleInit
367(
368    const std::string python_module_name,
369    const char *session_dictionary_name,
370    lldb::DebuggerSP& debugger
371);
372
373#else
374
375extern "C" void init_lldb(void);
376
377// Usually defined in the SWIG source file, but we have sripting disabled
378extern "C" void
379init_lldb(void)
380{
381}
382
383#endif
384
385void
386SBCommandInterpreter::InitializeSWIG ()
387{
388    static bool g_initialized = false;
389    if (!g_initialized)
390    {
391        g_initialized = true;
392#ifndef LLDB_DISABLE_PYTHON
393        ScriptInterpreter::InitializeInterpreter (init_lldb,
394                                                  LLDBSwigPythonBreakpointCallbackFunction,
395                                                  LLDBSwigPythonCallTypeScript,
396                                                  LLDBSwigPythonCreateSyntheticProvider,
397                                                  LLDBSwigPython_CalculateNumChildren,
398                                                  LLDBSwigPython_GetChildAtIndex,
399                                                  LLDBSwigPython_GetIndexOfChildWithName,
400                                                  LLDBSWIGPython_CastPyObjectToSBValue,
401                                                  LLDBSwigPython_UpdateSynthProviderInstance,
402                                                  LLDBSwigPythonCallCommand,
403                                                  LLDBSwigPythonCallModuleInit);
404#endif
405    }
406}
407