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 28 using namespace lldb; 29 using namespace lldb_private; 30 31 32 SBCommandInterpreter::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 42 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) : 43 m_opaque_ptr (rhs.m_opaque_ptr) 44 { 45 } 46 47 const SBCommandInterpreter & 48 SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs) 49 { 50 m_opaque_ptr = rhs.m_opaque_ptr; 51 return *this; 52 } 53 54 SBCommandInterpreter::~SBCommandInterpreter () 55 { 56 } 57 58 bool 59 SBCommandInterpreter::IsValid() const 60 { 61 return m_opaque_ptr != NULL; 62 } 63 64 65 bool 66 SBCommandInterpreter::CommandExists (const char *cmd) 67 { 68 if (cmd && m_opaque_ptr) 69 return m_opaque_ptr->CommandExists (cmd); 70 return false; 71 } 72 73 bool 74 SBCommandInterpreter::AliasExists (const char *cmd) 75 { 76 if (cmd && m_opaque_ptr) 77 return m_opaque_ptr->AliasExists (cmd); 78 return false; 79 } 80 81 lldb::ReturnStatus 82 SBCommandInterpreter::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 (command_line && 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.Lock(target_sp->GetAPIMutex()); 97 m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref()); 98 } 99 else 100 { 101 result->AppendError ("SBCommandInterpreter or the command line 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 118 int 119 SBCommandInterpreter::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 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 127 int num_completions = 0; 128 129 // Sanity check the arguments that are passed in: 130 // cursor & last_char have to be within the current_line. 131 if (current_line == NULL || cursor == NULL || last_char == NULL) 132 return 0; 133 134 if (cursor < current_line || last_char < current_line) 135 return 0; 136 137 size_t current_line_size = strlen (current_line); 138 if (cursor - current_line > current_line_size || last_char - current_line > current_line_size) 139 return 0; 140 141 if (log) 142 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %lld, last char at: %lld, match_start_point: %d, max_return_elements: %d)", 143 m_opaque_ptr, current_line, (uint64_t) (cursor - current_line), (uint64_t) (last_char - current_line), match_start_point, max_return_elements); 144 145 if (m_opaque_ptr) 146 { 147 lldb_private::StringList lldb_matches; 148 num_completions = m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point, 149 max_return_elements, lldb_matches); 150 151 SBStringList temp_list (&lldb_matches); 152 matches.AppendList (temp_list); 153 } 154 if (log) 155 log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", m_opaque_ptr, num_completions); 156 157 return num_completions; 158 } 159 160 int 161 SBCommandInterpreter::HandleCompletion (const char *current_line, 162 uint32_t cursor_pos, 163 int match_start_point, 164 int max_return_elements, 165 lldb::SBStringList &matches) 166 { 167 const char *cursor = current_line + cursor_pos; 168 const char *last_char = current_line + strlen (current_line); 169 return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches); 170 } 171 172 bool 173 SBCommandInterpreter::HasCommands () 174 { 175 if (m_opaque_ptr) 176 return m_opaque_ptr->HasCommands(); 177 return false; 178 } 179 180 bool 181 SBCommandInterpreter::HasAliases () 182 { 183 if (m_opaque_ptr) 184 return m_opaque_ptr->HasAliases(); 185 return false; 186 } 187 188 bool 189 SBCommandInterpreter::HasAliasOptions () 190 { 191 if (m_opaque_ptr) 192 return m_opaque_ptr->HasAliasOptions (); 193 return false; 194 } 195 196 SBProcess 197 SBCommandInterpreter::GetProcess () 198 { 199 SBProcess sb_process; 200 ProcessSP process_sp; 201 if (m_opaque_ptr) 202 { 203 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 204 if (target_sp) 205 { 206 Mutex::Locker api_locker(target_sp->GetAPIMutex()); 207 process_sp = target_sp->GetProcessSP(); 208 sb_process.SetSP(process_sp); 209 } 210 } 211 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 212 213 if (log) 214 log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", 215 m_opaque_ptr, process_sp.get()); 216 217 218 return sb_process; 219 } 220 221 CommandInterpreter * 222 SBCommandInterpreter::get () 223 { 224 return m_opaque_ptr; 225 } 226 227 CommandInterpreter & 228 SBCommandInterpreter::ref () 229 { 230 assert (m_opaque_ptr); 231 return *m_opaque_ptr; 232 } 233 234 void 235 SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter) 236 { 237 m_opaque_ptr = interpreter; 238 } 239 240 void 241 SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result) 242 { 243 result.Clear(); 244 if (m_opaque_ptr) 245 { 246 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 247 Mutex::Locker api_locker; 248 if (target_sp) 249 api_locker.Lock(target_sp->GetAPIMutex()); 250 m_opaque_ptr->SourceInitFile (false, result.ref()); 251 } 252 else 253 { 254 result->AppendError ("SBCommandInterpreter is not valid"); 255 result->SetStatus (eReturnStatusFailed); 256 } 257 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 258 259 if (log) 260 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))", 261 m_opaque_ptr, result.get()); 262 263 } 264 265 void 266 SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result) 267 { 268 result.Clear(); 269 if (m_opaque_ptr) 270 { 271 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 272 Mutex::Locker api_locker; 273 if (target_sp) 274 api_locker.Lock(target_sp->GetAPIMutex()); 275 m_opaque_ptr->SourceInitFile (true, result.ref()); 276 } 277 else 278 { 279 result->AppendError ("SBCommandInterpreter is not valid"); 280 result->SetStatus (eReturnStatusFailed); 281 } 282 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 283 284 if (log) 285 log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))", 286 m_opaque_ptr, result.get()); 287 } 288 289 SBBroadcaster 290 SBCommandInterpreter::GetBroadcaster () 291 { 292 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 293 294 SBBroadcaster broadcaster (m_opaque_ptr, false); 295 296 if (log) 297 log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", 298 m_opaque_ptr, broadcaster.get()); 299 300 return broadcaster; 301 } 302 303 const char * 304 SBCommandInterpreter::GetBroadcasterClass () 305 { 306 return Communication::GetStaticBroadcasterClass().AsCString(); 307 } 308 309 const char * 310 SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) 311 { 312 return CommandObject::GetArgumentTypeAsCString (arg_type); 313 } 314 315 const char * 316 SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) 317 { 318 return CommandObject::GetArgumentDescriptionAsCString (arg_type); 319 } 320 321 bool 322 SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name, 323 lldb::CommandOverrideCallback callback, 324 void *baton) 325 { 326 if (command_name && command_name[0] && m_opaque_ptr) 327 { 328 std::string command_name_str (command_name); 329 CommandObject *cmd_obj = m_opaque_ptr->GetCommandObjectForCommand(command_name_str); 330 if (cmd_obj) 331 { 332 assert(command_name_str.empty()); 333 cmd_obj->SetOverrideCallback (callback, baton); 334 return true; 335 } 336 } 337 return false; 338 } 339 340 #ifndef LLDB_DISABLE_PYTHON 341 342 // Defined in the SWIG source file 343 extern "C" void 344 init_lldb(void); 345 346 #else 347 348 extern "C" void init_lldb(void); 349 350 // Usually defined in the SWIG source file, but we have sripting disabled 351 extern "C" void 352 init_lldb(void) 353 { 354 } 355 356 #endif 357 358 void 359 SBCommandInterpreter::InitializeSWIG () 360 { 361 static bool g_initialized = false; 362 if (!g_initialized) 363 { 364 g_initialized = true; 365 #ifndef LLDB_DISABLE_PYTHON 366 ScriptInterpreter::InitializeInterpreter (init_lldb); 367 #endif 368 } 369 } 370 371