1 //===-- CommandInterpreter.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-python.h" 11 12 #include <string> 13 #include <vector> 14 15 #include <getopt.h> 16 #include <stdlib.h> 17 18 #include "CommandObjectScript.h" 19 #include "lldb/Interpreter/CommandObjectRegexCommand.h" 20 21 #include "../Commands/CommandObjectApropos.h" 22 #include "../Commands/CommandObjectArgs.h" 23 #include "../Commands/CommandObjectBreakpoint.h" 24 #include "../Commands/CommandObjectDisassemble.h" 25 #include "../Commands/CommandObjectExpression.h" 26 #include "../Commands/CommandObjectFrame.h" 27 #include "../Commands/CommandObjectHelp.h" 28 #include "../Commands/CommandObjectLog.h" 29 #include "../Commands/CommandObjectMemory.h" 30 #include "../Commands/CommandObjectPlatform.h" 31 #include "../Commands/CommandObjectPlugin.h" 32 #include "../Commands/CommandObjectProcess.h" 33 #include "../Commands/CommandObjectQuit.h" 34 #include "../Commands/CommandObjectRegister.h" 35 #include "../Commands/CommandObjectSettings.h" 36 #include "../Commands/CommandObjectSource.h" 37 #include "../Commands/CommandObjectCommands.h" 38 #include "../Commands/CommandObjectSyntax.h" 39 #include "../Commands/CommandObjectTarget.h" 40 #include "../Commands/CommandObjectThread.h" 41 #include "../Commands/CommandObjectType.h" 42 #include "../Commands/CommandObjectVersion.h" 43 #include "../Commands/CommandObjectWatchpoint.h" 44 45 #include "lldb/Core/Debugger.h" 46 #include "lldb/Core/InputReader.h" 47 #include "lldb/Core/Log.h" 48 #include "lldb/Core/Stream.h" 49 #include "lldb/Core/Timer.h" 50 51 #include "lldb/Host/Host.h" 52 53 #include "lldb/Interpreter/Args.h" 54 #include "lldb/Interpreter/CommandReturnObject.h" 55 #include "lldb/Interpreter/CommandInterpreter.h" 56 #include "lldb/Interpreter/Options.h" 57 #include "lldb/Interpreter/ScriptInterpreterNone.h" 58 #include "lldb/Interpreter/ScriptInterpreterPython.h" 59 60 61 #include "lldb/Target/Process.h" 62 #include "lldb/Target/Thread.h" 63 #include "lldb/Target/TargetList.h" 64 65 #include "lldb/Utility/CleanUp.h" 66 67 using namespace lldb; 68 using namespace lldb_private; 69 70 71 static PropertyDefinition 72 g_properties[] = 73 { 74 { "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." }, 75 { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." }, 76 { NULL , OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL } 77 }; 78 79 enum 80 { 81 ePropertyExpandRegexAliases = 0, 82 ePropertyPromptOnQuit = 1 83 }; 84 85 ConstString & 86 CommandInterpreter::GetStaticBroadcasterClass () 87 { 88 static ConstString class_name ("lldb.commandInterpreter"); 89 return class_name; 90 } 91 92 CommandInterpreter::CommandInterpreter 93 ( 94 Debugger &debugger, 95 ScriptLanguage script_language, 96 bool synchronous_execution 97 ) : 98 Broadcaster (&debugger, "lldb.command-interpreter"), 99 Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))), 100 m_debugger (debugger), 101 m_synchronous_execution (synchronous_execution), 102 m_skip_lldbinit_files (false), 103 m_skip_app_init_files (false), 104 m_script_interpreter_ap (), 105 m_comment_char ('#'), 106 m_repeat_char ('!'), 107 m_batch_command_mode (false), 108 m_truncation_warning(eNoTruncation), 109 m_command_source_depth (0) 110 { 111 debugger.SetScriptLanguage (script_language); 112 SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit"); 113 SetEventName (eBroadcastBitResetPrompt, "reset-prompt"); 114 SetEventName (eBroadcastBitQuitCommandReceived, "quit"); 115 CheckInWithManager (); 116 m_collection_sp->Initialize (g_properties); 117 } 118 119 bool 120 CommandInterpreter::GetExpandRegexAliases () const 121 { 122 const uint32_t idx = ePropertyExpandRegexAliases; 123 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 124 } 125 126 bool 127 CommandInterpreter::GetPromptOnQuit () const 128 { 129 const uint32_t idx = ePropertyPromptOnQuit; 130 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 131 } 132 133 void 134 CommandInterpreter::Initialize () 135 { 136 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 137 138 CommandReturnObject result; 139 140 LoadCommandDictionary (); 141 142 // Set up some initial aliases. 143 CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false); 144 if (cmd_obj_sp) 145 { 146 AddAlias ("q", cmd_obj_sp); 147 AddAlias ("exit", cmd_obj_sp); 148 } 149 150 cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false); 151 if (cmd_obj_sp) 152 { 153 AddAlias ("attach", cmd_obj_sp); 154 } 155 156 cmd_obj_sp = GetCommandSPExact ("process detach",false); 157 if (cmd_obj_sp) 158 { 159 AddAlias ("detach", cmd_obj_sp); 160 } 161 162 cmd_obj_sp = GetCommandSPExact ("process continue", false); 163 if (cmd_obj_sp) 164 { 165 AddAlias ("c", cmd_obj_sp); 166 AddAlias ("continue", cmd_obj_sp); 167 } 168 169 cmd_obj_sp = GetCommandSPExact ("_regexp-break",false); 170 if (cmd_obj_sp) 171 AddAlias ("b", cmd_obj_sp); 172 173 cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false); 174 if (cmd_obj_sp) 175 AddAlias ("tbreak", cmd_obj_sp); 176 177 cmd_obj_sp = GetCommandSPExact ("thread step-inst", false); 178 if (cmd_obj_sp) 179 { 180 AddAlias ("stepi", cmd_obj_sp); 181 AddAlias ("si", cmd_obj_sp); 182 } 183 184 cmd_obj_sp = GetCommandSPExact ("thread step-inst-over", false); 185 if (cmd_obj_sp) 186 { 187 AddAlias ("nexti", cmd_obj_sp); 188 AddAlias ("ni", cmd_obj_sp); 189 } 190 191 cmd_obj_sp = GetCommandSPExact ("thread step-in", false); 192 if (cmd_obj_sp) 193 { 194 AddAlias ("s", cmd_obj_sp); 195 AddAlias ("step", cmd_obj_sp); 196 } 197 198 cmd_obj_sp = GetCommandSPExact ("thread step-over", false); 199 if (cmd_obj_sp) 200 { 201 AddAlias ("n", cmd_obj_sp); 202 AddAlias ("next", cmd_obj_sp); 203 } 204 205 cmd_obj_sp = GetCommandSPExact ("thread step-out", false); 206 if (cmd_obj_sp) 207 { 208 AddAlias ("finish", cmd_obj_sp); 209 } 210 211 cmd_obj_sp = GetCommandSPExact ("frame select", false); 212 if (cmd_obj_sp) 213 { 214 AddAlias ("f", cmd_obj_sp); 215 } 216 217 cmd_obj_sp = GetCommandSPExact ("thread select", false); 218 if (cmd_obj_sp) 219 { 220 AddAlias ("t", cmd_obj_sp); 221 } 222 223 cmd_obj_sp = GetCommandSPExact ("_regexp-list", false); 224 if (cmd_obj_sp) 225 { 226 AddAlias ("l", cmd_obj_sp); 227 AddAlias ("list", cmd_obj_sp); 228 } 229 230 cmd_obj_sp = GetCommandSPExact ("memory read", false); 231 if (cmd_obj_sp) 232 AddAlias ("x", cmd_obj_sp); 233 234 cmd_obj_sp = GetCommandSPExact ("_regexp-up", false); 235 if (cmd_obj_sp) 236 AddAlias ("up", cmd_obj_sp); 237 238 cmd_obj_sp = GetCommandSPExact ("_regexp-down", false); 239 if (cmd_obj_sp) 240 AddAlias ("down", cmd_obj_sp); 241 242 cmd_obj_sp = GetCommandSPExact ("_regexp-display", false); 243 if (cmd_obj_sp) 244 AddAlias ("display", cmd_obj_sp); 245 246 cmd_obj_sp = GetCommandSPExact ("disassemble", false); 247 if (cmd_obj_sp) 248 AddAlias ("dis", cmd_obj_sp); 249 250 cmd_obj_sp = GetCommandSPExact ("disassemble", false); 251 if (cmd_obj_sp) 252 AddAlias ("di", cmd_obj_sp); 253 254 255 256 cmd_obj_sp = GetCommandSPExact ("_regexp-undisplay", false); 257 if (cmd_obj_sp) 258 AddAlias ("undisplay", cmd_obj_sp); 259 260 cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false); 261 if (cmd_obj_sp) 262 AddAlias ("bt", cmd_obj_sp); 263 264 cmd_obj_sp = GetCommandSPExact ("target create", false); 265 if (cmd_obj_sp) 266 AddAlias ("file", cmd_obj_sp); 267 268 cmd_obj_sp = GetCommandSPExact ("target modules", false); 269 if (cmd_obj_sp) 270 AddAlias ("image", cmd_obj_sp); 271 272 273 OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector); 274 275 cmd_obj_sp = GetCommandSPExact ("expression", false); 276 if (cmd_obj_sp) 277 { 278 AddAlias ("expr", cmd_obj_sp); 279 280 ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp); 281 AddAlias ("p", cmd_obj_sp); 282 AddAlias ("print", cmd_obj_sp); 283 AddAlias ("call", cmd_obj_sp); 284 AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp); 285 AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp); 286 AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp); 287 288 alias_arguments_vector_sp.reset (new OptionArgVector); 289 ProcessAliasOptionsArgs (cmd_obj_sp, "-O --", alias_arguments_vector_sp); 290 AddAlias ("po", cmd_obj_sp); 291 AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp); 292 } 293 294 cmd_obj_sp = GetCommandSPExact ("process kill", false); 295 if (cmd_obj_sp) 296 { 297 AddAlias ("kill", cmd_obj_sp); 298 } 299 300 cmd_obj_sp = GetCommandSPExact ("process launch", false); 301 if (cmd_obj_sp) 302 { 303 alias_arguments_vector_sp.reset (new OptionArgVector); 304 #if defined (__arm__) 305 ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp); 306 #else 307 ProcessAliasOptionsArgs (cmd_obj_sp, "--shell=/bin/bash --", alias_arguments_vector_sp); 308 #endif 309 AddAlias ("r", cmd_obj_sp); 310 AddAlias ("run", cmd_obj_sp); 311 AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp); 312 AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp); 313 } 314 315 cmd_obj_sp = GetCommandSPExact ("target symbols add", false); 316 if (cmd_obj_sp) 317 { 318 AddAlias ("add-dsym", cmd_obj_sp); 319 } 320 321 cmd_obj_sp = GetCommandSPExact ("breakpoint set", false); 322 if (cmd_obj_sp) 323 { 324 alias_arguments_vector_sp.reset (new OptionArgVector); 325 ProcessAliasOptionsArgs (cmd_obj_sp, "--func-regex %1", alias_arguments_vector_sp); 326 AddAlias ("rbreak", cmd_obj_sp); 327 AddOrReplaceAliasOptions("rbreak", alias_arguments_vector_sp); 328 } 329 } 330 331 const char * 332 CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg) 333 { 334 // This function has not yet been implemented. 335 336 // Look for any embedded script command 337 // If found, 338 // get interpreter object from the command dictionary, 339 // call execute_one_command on it, 340 // get the results as a string, 341 // substitute that string for current stuff. 342 343 return arg; 344 } 345 346 347 void 348 CommandInterpreter::LoadCommandDictionary () 349 { 350 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 351 352 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT *** 353 // 354 // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref) 355 // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use 356 // the cross-referencing stuff) are created!!! 357 // 358 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT *** 359 360 361 // Command objects that inherit from CommandObjectCrossref must be created before other command objects 362 // are created. This is so that when another command is created that needs to go into a crossref object, 363 // the crossref object exists and is ready to take the cross reference. Put the cross referencing command 364 // objects into the CommandDictionary now, so they are ready for use when the other commands get created. 365 366 // Non-CommandObjectCrossref commands can now be created. 367 368 lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage(); 369 370 m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this)); 371 m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this)); 372 //m_command_dict["call"] = CommandObjectSP (new CommandObjectCall (*this)); 373 m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this)); 374 m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this)); 375 m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this)); 376 // m_command_dict["file"] = CommandObjectSP (new CommandObjectFile (*this)); 377 m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this)); 378 m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this)); 379 /// m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this)); 380 m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this)); 381 m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this)); 382 m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this)); 383 m_command_dict["plugin"] = CommandObjectSP (new CommandObjectPlugin (*this)); 384 m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (*this)); 385 m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit (*this)); 386 m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (*this)); 387 m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (*this, script_language)); 388 m_command_dict["settings"] = CommandObjectSP (new CommandObjectMultiwordSettings (*this)); 389 m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); 390 m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); 391 m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); 392 m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this)); 393 m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this)); 394 m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this)); 395 396 const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"}, 397 {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"}, 398 {"^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"}, 399 {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}, 400 {"^(-.*)$", "breakpoint set %1"}, 401 {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"}, 402 {"^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"}}; 403 404 size_t num_regexes = sizeof break_regexes/sizeof(char *[2]); 405 406 std::auto_ptr<CommandObjectRegexCommand> 407 break_regex_cmd_ap(new CommandObjectRegexCommand (*this, 408 "_regexp-break", 409 "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.", 410 "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2)); 411 412 if (break_regex_cmd_ap.get()) 413 { 414 bool success = true; 415 for (size_t i = 0; i < num_regexes; i++) 416 { 417 success = break_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], break_regexes[i][1]); 418 if (!success) 419 break; 420 } 421 success = break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); 422 423 if (success) 424 { 425 CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release()); 426 m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp; 427 } 428 } 429 430 std::auto_ptr<CommandObjectRegexCommand> 431 tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this, 432 "_regexp-tbreak", 433 "Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.", 434 "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2)); 435 436 if (tbreak_regex_cmd_ap.get()) 437 { 438 bool success = true; 439 for (size_t i = 0; i < num_regexes; i++) 440 { 441 // If you add a resultant command string longer than 1024 characters be sure to increase the size of this buffer. 442 char buffer[1024]; 443 int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o"); 444 assert (num_printed < 1024); 445 success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer); 446 if (!success) 447 break; 448 } 449 success = tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); 450 451 if (success) 452 { 453 CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release()); 454 m_command_dict[tbreak_regex_cmd_sp->GetCommandName ()] = tbreak_regex_cmd_sp; 455 } 456 } 457 458 std::auto_ptr<CommandObjectRegexCommand> 459 attach_regex_cmd_ap(new CommandObjectRegexCommand (*this, 460 "_regexp-attach", 461 "Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.", 462 "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]", 2)); 463 if (attach_regex_cmd_ap.get()) 464 { 465 if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") && 466 attach_regex_cmd_ap->AddRegexCommand("^(-.*|.* -.*)$", "process attach %1") && // Any options that are specified get passed to 'process attach' 467 attach_regex_cmd_ap->AddRegexCommand("^(.+)$", "process attach --name '%1'") && 468 attach_regex_cmd_ap->AddRegexCommand("^$", "process attach")) 469 { 470 CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release()); 471 m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp; 472 } 473 } 474 475 std::auto_ptr<CommandObjectRegexCommand> 476 down_regex_cmd_ap(new CommandObjectRegexCommand (*this, 477 "_regexp-down", 478 "Go down \"n\" frames in the stack (1 frame by default).", 479 "_regexp-down [n]", 2)); 480 if (down_regex_cmd_ap.get()) 481 { 482 if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") && 483 down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r -%1")) 484 { 485 CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release()); 486 m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp; 487 } 488 } 489 490 std::auto_ptr<CommandObjectRegexCommand> 491 up_regex_cmd_ap(new CommandObjectRegexCommand (*this, 492 "_regexp-up", 493 "Go up \"n\" frames in the stack (1 frame by default).", 494 "_regexp-up [n]", 2)); 495 if (up_regex_cmd_ap.get()) 496 { 497 if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") && 498 up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1")) 499 { 500 CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release()); 501 m_command_dict[up_regex_cmd_sp->GetCommandName ()] = up_regex_cmd_sp; 502 } 503 } 504 505 std::auto_ptr<CommandObjectRegexCommand> 506 display_regex_cmd_ap(new CommandObjectRegexCommand (*this, 507 "_regexp-display", 508 "Add an expression evaluation stop-hook.", 509 "_regexp-display expression", 2)); 510 if (display_regex_cmd_ap.get()) 511 { 512 if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\"")) 513 { 514 CommandObjectSP display_regex_cmd_sp(display_regex_cmd_ap.release()); 515 m_command_dict[display_regex_cmd_sp->GetCommandName ()] = display_regex_cmd_sp; 516 } 517 } 518 519 std::auto_ptr<CommandObjectRegexCommand> 520 undisplay_regex_cmd_ap(new CommandObjectRegexCommand (*this, 521 "_regexp-undisplay", 522 "Remove an expression evaluation stop-hook.", 523 "_regexp-undisplay stop-hook-number", 2)); 524 if (undisplay_regex_cmd_ap.get()) 525 { 526 if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1")) 527 { 528 CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_ap.release()); 529 m_command_dict[undisplay_regex_cmd_sp->GetCommandName ()] = undisplay_regex_cmd_sp; 530 } 531 } 532 533 std::auto_ptr<CommandObjectRegexCommand> 534 connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand (*this, 535 "gdb-remote", 536 "Connect to a remote GDB server. If no hostname is provided, localhost is assumed.", 537 "gdb-remote [<hostname>:]<portnum>", 2)); 538 if (connect_gdb_remote_cmd_ap.get()) 539 { 540 if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") && 541 connect_gdb_remote_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "process connect --plugin gdb-remote connect://localhost:%1")) 542 { 543 CommandObjectSP command_sp(connect_gdb_remote_cmd_ap.release()); 544 m_command_dict[command_sp->GetCommandName ()] = command_sp; 545 } 546 } 547 548 std::auto_ptr<CommandObjectRegexCommand> 549 connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand (*this, 550 "kdp-remote", 551 "Connect to a remote KDP server. udp port 41139 is the default port number.", 552 "kdp-remote <hostname>[:<portnum>]", 2)); 553 if (connect_kdp_remote_cmd_ap.get()) 554 { 555 if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") && 556 connect_kdp_remote_cmd_ap->AddRegexCommand("^(.+)$", "process connect --plugin kdp-remote udp://%1:41139")) 557 { 558 CommandObjectSP command_sp(connect_kdp_remote_cmd_ap.release()); 559 m_command_dict[command_sp->GetCommandName ()] = command_sp; 560 } 561 } 562 563 std::auto_ptr<CommandObjectRegexCommand> 564 bt_regex_cmd_ap(new CommandObjectRegexCommand (*this, 565 "_regexp-bt", 566 "Show a backtrace. An optional argument is accepted; if that argument is a number, it specifies the number of frames to display. If that argument is 'all', full backtraces of all threads are displayed.", 567 "bt [<digit>|all]", 2)); 568 if (bt_regex_cmd_ap.get()) 569 { 570 // accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace 571 // three frames you would do "bt -c 3" but the intention is to have this emulate the gdb "bt" command and 572 // so now "bt 3" is the preferred form, in line with gdb. 573 if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "thread backtrace -c %1") && 574 bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$", "thread backtrace -c %1") && 575 bt_regex_cmd_ap->AddRegexCommand("^all$", "thread backtrace all") && 576 bt_regex_cmd_ap->AddRegexCommand("^$", "thread backtrace")) 577 { 578 CommandObjectSP command_sp(bt_regex_cmd_ap.release()); 579 m_command_dict[command_sp->GetCommandName ()] = command_sp; 580 } 581 } 582 583 std::auto_ptr<CommandObjectRegexCommand> 584 list_regex_cmd_ap(new CommandObjectRegexCommand (*this, 585 "_regexp-list", 586 "Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.", 587 "_regexp-list [<line>]\n_regexp-attach [<file>:<line>]\n_regexp-attach [<file>:<line>]", 2)); 588 if (list_regex_cmd_ap.get()) 589 { 590 if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") && 591 list_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "source list --file '%1' --line %2") && 592 list_regex_cmd_ap->AddRegexCommand("^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "source list --address %1") && 593 list_regex_cmd_ap->AddRegexCommand("^(.+)$", "source list --name \"%1\"") && 594 list_regex_cmd_ap->AddRegexCommand("^$", "source list")) 595 { 596 CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release()); 597 m_command_dict[list_regex_cmd_sp->GetCommandName ()] = list_regex_cmd_sp; 598 } 599 } 600 601 } 602 603 int 604 CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases, 605 StringList &matches) 606 { 607 CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches); 608 609 if (include_aliases) 610 { 611 CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches); 612 } 613 614 return matches.GetSize(); 615 } 616 617 CommandObjectSP 618 CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches) 619 { 620 CommandObject::CommandMap::iterator pos; 621 CommandObjectSP command_sp; 622 623 std::string cmd(cmd_cstr); 624 625 if (HasCommands()) 626 { 627 pos = m_command_dict.find(cmd); 628 if (pos != m_command_dict.end()) 629 command_sp = pos->second; 630 } 631 632 if (include_aliases && HasAliases()) 633 { 634 pos = m_alias_dict.find(cmd); 635 if (pos != m_alias_dict.end()) 636 command_sp = pos->second; 637 } 638 639 if (HasUserCommands()) 640 { 641 pos = m_user_dict.find(cmd); 642 if (pos != m_user_dict.end()) 643 command_sp = pos->second; 644 } 645 646 if (!exact && !command_sp) 647 { 648 // We will only get into here if we didn't find any exact matches. 649 650 CommandObjectSP user_match_sp, alias_match_sp, real_match_sp; 651 652 StringList local_matches; 653 if (matches == NULL) 654 matches = &local_matches; 655 656 unsigned int num_cmd_matches = 0; 657 unsigned int num_alias_matches = 0; 658 unsigned int num_user_matches = 0; 659 660 // Look through the command dictionaries one by one, and if we get only one match from any of 661 // them in toto, then return that, otherwise return an empty CommandObjectSP and the list of matches. 662 663 if (HasCommands()) 664 { 665 num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches); 666 } 667 668 if (num_cmd_matches == 1) 669 { 670 cmd.assign(matches->GetStringAtIndex(0)); 671 pos = m_command_dict.find(cmd); 672 if (pos != m_command_dict.end()) 673 real_match_sp = pos->second; 674 } 675 676 if (include_aliases && HasAliases()) 677 { 678 num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches); 679 680 } 681 682 if (num_alias_matches == 1) 683 { 684 cmd.assign(matches->GetStringAtIndex (num_cmd_matches)); 685 pos = m_alias_dict.find(cmd); 686 if (pos != m_alias_dict.end()) 687 alias_match_sp = pos->second; 688 } 689 690 if (HasUserCommands()) 691 { 692 num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches); 693 } 694 695 if (num_user_matches == 1) 696 { 697 cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches)); 698 699 pos = m_user_dict.find (cmd); 700 if (pos != m_user_dict.end()) 701 user_match_sp = pos->second; 702 } 703 704 // If we got exactly one match, return that, otherwise return the match list. 705 706 if (num_user_matches + num_cmd_matches + num_alias_matches == 1) 707 { 708 if (num_cmd_matches) 709 return real_match_sp; 710 else if (num_alias_matches) 711 return alias_match_sp; 712 else 713 return user_match_sp; 714 } 715 } 716 else if (matches && command_sp) 717 { 718 matches->AppendString (cmd_cstr); 719 } 720 721 722 return command_sp; 723 } 724 725 bool 726 CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace) 727 { 728 if (name && name[0]) 729 { 730 std::string name_sstr(name); 731 bool found = (m_command_dict.find (name_sstr) != m_command_dict.end()); 732 if (found && !can_replace) 733 return false; 734 if (found && m_command_dict[name_sstr]->IsRemovable() == false) 735 return false; 736 m_command_dict[name_sstr] = cmd_sp; 737 return true; 738 } 739 return false; 740 } 741 742 bool 743 CommandInterpreter::AddUserCommand (std::string name, 744 const lldb::CommandObjectSP &cmd_sp, 745 bool can_replace) 746 { 747 if (!name.empty()) 748 { 749 750 const char* name_cstr = name.c_str(); 751 752 // do not allow replacement of internal commands 753 if (CommandExists(name_cstr)) 754 { 755 if (can_replace == false) 756 return false; 757 if (m_command_dict[name]->IsRemovable() == false) 758 return false; 759 } 760 761 if (UserCommandExists(name_cstr)) 762 { 763 if (can_replace == false) 764 return false; 765 if (m_user_dict[name]->IsRemovable() == false) 766 return false; 767 } 768 769 m_user_dict[name] = cmd_sp; 770 return true; 771 } 772 return false; 773 } 774 775 CommandObjectSP 776 CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases) 777 { 778 Args cmd_words (cmd_cstr); // Break up the command string into words, in case it's a multi-word command. 779 CommandObjectSP ret_val; // Possibly empty return value. 780 781 if (cmd_cstr == NULL) 782 return ret_val; 783 784 if (cmd_words.GetArgumentCount() == 1) 785 return GetCommandSP(cmd_cstr, include_aliases, true, NULL); 786 else 787 { 788 // We have a multi-word command (seemingly), so we need to do more work. 789 // First, get the cmd_obj_sp for the first word in the command. 790 CommandObjectSP cmd_obj_sp = GetCommandSP (cmd_words.GetArgumentAtIndex (0), include_aliases, true, NULL); 791 if (cmd_obj_sp.get() != NULL) 792 { 793 // Loop through the rest of the words in the command (everything passed in was supposed to be part of a 794 // command name), and find the appropriate sub-command SP for each command word.... 795 size_t end = cmd_words.GetArgumentCount(); 796 for (size_t j= 1; j < end; ++j) 797 { 798 if (cmd_obj_sp->IsMultiwordObject()) 799 { 800 cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j)); 801 if (cmd_obj_sp.get() == NULL) 802 // The sub-command name was invalid. Fail and return the empty 'ret_val'. 803 return ret_val; 804 } 805 else 806 // We have more words in the command name, but we don't have a multiword object. Fail and return 807 // empty 'ret_val'. 808 return ret_val; 809 } 810 // We successfully looped through all the command words and got valid command objects for them. Assign the 811 // last object retrieved to 'ret_val'. 812 ret_val = cmd_obj_sp; 813 } 814 } 815 return ret_val; 816 } 817 818 CommandObject * 819 CommandInterpreter::GetCommandObjectExact (const char *cmd_cstr, bool include_aliases) 820 { 821 return GetCommandSPExact (cmd_cstr, include_aliases).get(); 822 } 823 824 CommandObject * 825 CommandInterpreter::GetCommandObject (const char *cmd_cstr, StringList *matches) 826 { 827 CommandObject *command_obj = GetCommandSP (cmd_cstr, false, true, matches).get(); 828 829 // If we didn't find an exact match to the command string in the commands, look in 830 // the aliases. 831 832 if (command_obj == NULL) 833 { 834 command_obj = GetCommandSP (cmd_cstr, true, true, matches).get(); 835 } 836 837 // Finally, if there wasn't an exact match among the aliases, look for an inexact match 838 // in both the commands and the aliases. 839 840 if (command_obj == NULL) 841 command_obj = GetCommandSP(cmd_cstr, true, false, matches).get(); 842 843 return command_obj; 844 } 845 846 bool 847 CommandInterpreter::CommandExists (const char *cmd) 848 { 849 return m_command_dict.find(cmd) != m_command_dict.end(); 850 } 851 852 bool 853 CommandInterpreter::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp, 854 const char *options_args, 855 OptionArgVectorSP &option_arg_vector_sp) 856 { 857 bool success = true; 858 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 859 860 if (!options_args || (strlen (options_args) < 1)) 861 return true; 862 863 std::string options_string (options_args); 864 Args args (options_args); 865 CommandReturnObject result; 866 // Check to see if the command being aliased can take any command options. 867 Options *options = cmd_obj_sp->GetOptions (); 868 if (options) 869 { 870 // See if any options were specified as part of the alias; if so, handle them appropriately. 871 options->NotifyOptionParsingStarting (); 872 args.Unshift ("dummy_arg"); 873 args.ParseAliasOptions (*options, result, option_arg_vector, options_string); 874 args.Shift (); 875 if (result.Succeeded()) 876 options->VerifyPartialOptions (result); 877 if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted) 878 { 879 result.AppendError ("Unable to create requested alias.\n"); 880 return false; 881 } 882 } 883 884 if (!options_string.empty()) 885 { 886 if (cmd_obj_sp->WantsRawCommandString ()) 887 option_arg_vector->push_back (OptionArgPair ("<argument>", 888 OptionArgValue (-1, 889 options_string))); 890 else 891 { 892 const size_t argc = args.GetArgumentCount(); 893 for (size_t i = 0; i < argc; ++i) 894 if (strcmp (args.GetArgumentAtIndex (i), "") != 0) 895 option_arg_vector->push_back 896 (OptionArgPair ("<argument>", 897 OptionArgValue (-1, 898 std::string (args.GetArgumentAtIndex (i))))); 899 } 900 } 901 902 return success; 903 } 904 905 bool 906 CommandInterpreter::AliasExists (const char *cmd) 907 { 908 return m_alias_dict.find(cmd) != m_alias_dict.end(); 909 } 910 911 bool 912 CommandInterpreter::UserCommandExists (const char *cmd) 913 { 914 return m_user_dict.find(cmd) != m_user_dict.end(); 915 } 916 917 void 918 CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp) 919 { 920 command_obj_sp->SetIsAlias (true); 921 m_alias_dict[alias_name] = command_obj_sp; 922 } 923 924 bool 925 CommandInterpreter::RemoveAlias (const char *alias_name) 926 { 927 CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name); 928 if (pos != m_alias_dict.end()) 929 { 930 m_alias_dict.erase(pos); 931 return true; 932 } 933 return false; 934 } 935 bool 936 CommandInterpreter::RemoveUser (const char *alias_name) 937 { 938 CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name); 939 if (pos != m_user_dict.end()) 940 { 941 m_user_dict.erase(pos); 942 return true; 943 } 944 return false; 945 } 946 947 void 948 CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string) 949 { 950 help_string.Printf ("'%s", command_name); 951 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 952 953 if (option_arg_vector_sp) 954 { 955 OptionArgVector *options = option_arg_vector_sp.get(); 956 for (int i = 0; i < options->size(); ++i) 957 { 958 OptionArgPair cur_option = (*options)[i]; 959 std::string opt = cur_option.first; 960 OptionArgValue value_pair = cur_option.second; 961 std::string value = value_pair.second; 962 if (opt.compare("<argument>") == 0) 963 { 964 help_string.Printf (" %s", value.c_str()); 965 } 966 else 967 { 968 help_string.Printf (" %s", opt.c_str()); 969 if ((value.compare ("<no-argument>") != 0) 970 && (value.compare ("<need-argument") != 0)) 971 { 972 help_string.Printf (" %s", value.c_str()); 973 } 974 } 975 } 976 } 977 978 help_string.Printf ("'"); 979 } 980 981 size_t 982 CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict) 983 { 984 CommandObject::CommandMap::const_iterator pos; 985 CommandObject::CommandMap::const_iterator end = dict.end(); 986 size_t max_len = 0; 987 988 for (pos = dict.begin(); pos != end; ++pos) 989 { 990 size_t len = pos->first.size(); 991 if (max_len < len) 992 max_len = len; 993 } 994 return max_len; 995 } 996 997 void 998 CommandInterpreter::GetHelp (CommandReturnObject &result, 999 uint32_t cmd_types) 1000 { 1001 CommandObject::CommandMap::const_iterator pos; 1002 size_t max_len = FindLongestCommandWord (m_command_dict); 1003 1004 if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin ) 1005 { 1006 1007 result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); 1008 result.AppendMessage(""); 1009 1010 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 1011 { 1012 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 1013 max_len); 1014 } 1015 result.AppendMessage(""); 1016 1017 } 1018 1019 if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases )) 1020 { 1021 result.AppendMessage("The following is a list of your current command abbreviations " 1022 "(see 'help command alias' for more info):"); 1023 result.AppendMessage(""); 1024 max_len = FindLongestCommandWord (m_alias_dict); 1025 1026 for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos) 1027 { 1028 StreamString sstr; 1029 StreamString translation_and_help; 1030 std::string entry_name = pos->first; 1031 std::string second_entry = pos->second.get()->GetCommandName(); 1032 GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr); 1033 1034 translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp()); 1035 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", 1036 translation_and_help.GetData(), max_len); 1037 } 1038 result.AppendMessage(""); 1039 } 1040 1041 if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef )) 1042 { 1043 result.AppendMessage ("The following is a list of your current user-defined commands:"); 1044 result.AppendMessage(""); 1045 max_len = FindLongestCommandWord (m_user_dict); 1046 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) 1047 { 1048 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 1049 max_len); 1050 } 1051 result.AppendMessage(""); 1052 } 1053 1054 result.AppendMessage("For more information on any particular command, try 'help <command-name>'."); 1055 } 1056 1057 CommandObject * 1058 CommandInterpreter::GetCommandObjectForCommand (std::string &command_string) 1059 { 1060 // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will 1061 // eventually be invoked by the given command line. 1062 1063 CommandObject *cmd_obj = NULL; 1064 std::string white_space (" \t\v"); 1065 size_t start = command_string.find_first_not_of (white_space); 1066 size_t end = 0; 1067 bool done = false; 1068 while (!done) 1069 { 1070 if (start != std::string::npos) 1071 { 1072 // Get the next word from command_string. 1073 end = command_string.find_first_of (white_space, start); 1074 if (end == std::string::npos) 1075 end = command_string.size(); 1076 std::string cmd_word = command_string.substr (start, end - start); 1077 1078 if (cmd_obj == NULL) 1079 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid 1080 // command or alias. 1081 cmd_obj = GetCommandObject (cmd_word.c_str()); 1082 else if (cmd_obj->IsMultiwordObject ()) 1083 { 1084 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object. 1085 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str()); 1086 if (sub_cmd_obj) 1087 cmd_obj = sub_cmd_obj; 1088 else // cmd_word was not a valid sub-command word, so we are donee 1089 done = true; 1090 } 1091 else 1092 // We have a cmd_obj and it is not a multi-word object, so we are done. 1093 done = true; 1094 1095 // If we didn't find a valid command object, or our command object is not a multi-word object, or 1096 // we are at the end of the command_string, then we are done. Otherwise, find the start of the 1097 // next word. 1098 1099 if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size()) 1100 done = true; 1101 else 1102 start = command_string.find_first_not_of (white_space, end); 1103 } 1104 else 1105 // Unable to find any more words. 1106 done = true; 1107 } 1108 1109 if (end == command_string.size()) 1110 command_string.clear(); 1111 else 1112 command_string = command_string.substr(end); 1113 1114 return cmd_obj; 1115 } 1116 1117 static const char *k_white_space = " \t\v"; 1118 static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; 1119 static void 1120 StripLeadingSpaces (std::string &s) 1121 { 1122 if (!s.empty()) 1123 { 1124 size_t pos = s.find_first_not_of (k_white_space); 1125 if (pos == std::string::npos) 1126 s.clear(); 1127 else if (pos == 0) 1128 return; 1129 s.erase (0, pos); 1130 } 1131 } 1132 1133 static size_t 1134 FindArgumentTerminator (const std::string &s) 1135 { 1136 const size_t s_len = s.size(); 1137 size_t offset = 0; 1138 while (offset < s_len) 1139 { 1140 size_t pos = s.find ("--", offset); 1141 if (pos == std::string::npos) 1142 break; 1143 if (pos > 0) 1144 { 1145 if (isspace(s[pos-1])) 1146 { 1147 // Check if the string ends "\s--" (where \s is a space character) 1148 // or if we have "\s--\s". 1149 if ((pos + 2 >= s_len) || isspace(s[pos+2])) 1150 { 1151 return pos; 1152 } 1153 } 1154 } 1155 offset = pos + 2; 1156 } 1157 return std::string::npos; 1158 } 1159 1160 static bool 1161 ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char "e_char) 1162 { 1163 command.clear(); 1164 suffix.clear(); 1165 StripLeadingSpaces (command_string); 1166 1167 bool result = false; 1168 quote_char = '\0'; 1169 1170 if (!command_string.empty()) 1171 { 1172 const char first_char = command_string[0]; 1173 if (first_char == '\'' || first_char == '"') 1174 { 1175 quote_char = first_char; 1176 const size_t end_quote_pos = command_string.find (quote_char, 1); 1177 if (end_quote_pos == std::string::npos) 1178 { 1179 command.swap (command_string); 1180 command_string.erase (); 1181 } 1182 else 1183 { 1184 command.assign (command_string, 1, end_quote_pos - 1); 1185 if (end_quote_pos + 1 < command_string.size()) 1186 command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1)); 1187 else 1188 command_string.erase (); 1189 } 1190 } 1191 else 1192 { 1193 const size_t first_space_pos = command_string.find_first_of (k_white_space); 1194 if (first_space_pos == std::string::npos) 1195 { 1196 command.swap (command_string); 1197 command_string.erase(); 1198 } 1199 else 1200 { 1201 command.assign (command_string, 0, first_space_pos); 1202 command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos)); 1203 } 1204 } 1205 result = true; 1206 } 1207 1208 1209 if (!command.empty()) 1210 { 1211 // actual commands can't start with '-' or '_' 1212 if (command[0] != '-' && command[0] != '_') 1213 { 1214 size_t pos = command.find_first_not_of(k_valid_command_chars); 1215 if (pos > 0 && pos != std::string::npos) 1216 { 1217 suffix.assign (command.begin() + pos, command.end()); 1218 command.erase (pos); 1219 } 1220 } 1221 } 1222 1223 return result; 1224 } 1225 1226 CommandObject * 1227 CommandInterpreter::BuildAliasResult (const char *alias_name, 1228 std::string &raw_input_string, 1229 std::string &alias_result, 1230 CommandReturnObject &result) 1231 { 1232 CommandObject *alias_cmd_obj = NULL; 1233 Args cmd_args (raw_input_string.c_str()); 1234 alias_cmd_obj = GetCommandObject (alias_name); 1235 StreamString result_str; 1236 1237 if (alias_cmd_obj) 1238 { 1239 std::string alias_name_str = alias_name; 1240 if ((cmd_args.GetArgumentCount() == 0) 1241 || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)) 1242 cmd_args.Unshift (alias_name); 1243 1244 result_str.Printf ("%s", alias_cmd_obj->GetCommandName ()); 1245 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 1246 1247 if (option_arg_vector_sp.get()) 1248 { 1249 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 1250 1251 for (int i = 0; i < option_arg_vector->size(); ++i) 1252 { 1253 OptionArgPair option_pair = (*option_arg_vector)[i]; 1254 OptionArgValue value_pair = option_pair.second; 1255 int value_type = value_pair.first; 1256 std::string option = option_pair.first; 1257 std::string value = value_pair.second; 1258 if (option.compare ("<argument>") == 0) 1259 result_str.Printf (" %s", value.c_str()); 1260 else 1261 { 1262 result_str.Printf (" %s", option.c_str()); 1263 if (value_type != optional_argument) 1264 result_str.Printf (" "); 1265 if (value.compare ("<no_argument>") != 0) 1266 { 1267 int index = GetOptionArgumentPosition (value.c_str()); 1268 if (index == 0) 1269 result_str.Printf ("%s", value.c_str()); 1270 else if (index >= cmd_args.GetArgumentCount()) 1271 { 1272 1273 result.AppendErrorWithFormat 1274 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 1275 index); 1276 result.SetStatus (eReturnStatusFailed); 1277 return alias_cmd_obj; 1278 } 1279 else 1280 { 1281 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 1282 if (strpos != std::string::npos) 1283 raw_input_string = raw_input_string.erase (strpos, 1284 strlen (cmd_args.GetArgumentAtIndex (index))); 1285 result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index)); 1286 } 1287 } 1288 } 1289 } 1290 } 1291 1292 alias_result = result_str.GetData(); 1293 } 1294 return alias_cmd_obj; 1295 } 1296 1297 Error 1298 CommandInterpreter::PreprocessCommand (std::string &command) 1299 { 1300 // The command preprocessor needs to do things to the command 1301 // line before any parsing of arguments or anything else is done. 1302 // The only current stuff that gets proprocessed is anyting enclosed 1303 // in backtick ('`') characters is evaluated as an expression and 1304 // the result of the expression must be a scalar that can be substituted 1305 // into the command. An example would be: 1306 // (lldb) memory read `$rsp + 20` 1307 Error error; // Error for any expressions that might not evaluate 1308 size_t start_backtick; 1309 size_t pos = 0; 1310 while ((start_backtick = command.find ('`', pos)) != std::string::npos) 1311 { 1312 if (start_backtick > 0 && command[start_backtick-1] == '\\') 1313 { 1314 // The backtick was preceeded by a '\' character, remove the slash 1315 // and don't treat the backtick as the start of an expression 1316 command.erase(start_backtick-1, 1); 1317 // No need to add one to start_backtick since we just deleted a char 1318 pos = start_backtick; 1319 } 1320 else 1321 { 1322 const size_t expr_content_start = start_backtick + 1; 1323 const size_t end_backtick = command.find ('`', expr_content_start); 1324 if (end_backtick == std::string::npos) 1325 return error; 1326 else if (end_backtick == expr_content_start) 1327 { 1328 // Empty expression (two backticks in a row) 1329 command.erase (start_backtick, 2); 1330 } 1331 else 1332 { 1333 std::string expr_str (command, expr_content_start, end_backtick - expr_content_start); 1334 1335 ExecutionContext exe_ctx(GetExecutionContext()); 1336 Target *target = exe_ctx.GetTargetPtr(); 1337 // Get a dummy target to allow for calculator mode while processing backticks. 1338 // This also helps break the infinite loop caused when target is null. 1339 if (!target) 1340 target = Host::GetDummyTarget(GetDebugger()).get(); 1341 if (target) 1342 { 1343 ValueObjectSP expr_result_valobj_sp; 1344 1345 EvaluateExpressionOptions options; 1346 options.SetCoerceToId(false) 1347 .SetUnwindOnError(true) 1348 .SetIgnoreBreakpoints(true) 1349 .SetKeepInMemory(false) 1350 .SetRunOthers(true) 1351 .SetTimeoutUsec(0); 1352 1353 ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), 1354 exe_ctx.GetFramePtr(), 1355 expr_result_valobj_sp, 1356 options); 1357 1358 if (expr_result == eExecutionCompleted) 1359 { 1360 Scalar scalar; 1361 if (expr_result_valobj_sp->ResolveValue (scalar)) 1362 { 1363 command.erase (start_backtick, end_backtick - start_backtick + 1); 1364 StreamString value_strm; 1365 const bool show_type = false; 1366 scalar.GetValue (&value_strm, show_type); 1367 size_t value_string_size = value_strm.GetSize(); 1368 if (value_string_size) 1369 { 1370 command.insert (start_backtick, value_strm.GetData(), value_string_size); 1371 pos = start_backtick + value_string_size; 1372 continue; 1373 } 1374 else 1375 { 1376 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); 1377 } 1378 } 1379 else 1380 { 1381 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); 1382 } 1383 } 1384 else 1385 { 1386 if (expr_result_valobj_sp) 1387 error = expr_result_valobj_sp->GetError(); 1388 if (error.Success()) 1389 { 1390 1391 switch (expr_result) 1392 { 1393 case eExecutionSetupError: 1394 error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str()); 1395 break; 1396 case eExecutionCompleted: 1397 break; 1398 case eExecutionDiscarded: 1399 error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str()); 1400 break; 1401 case eExecutionInterrupted: 1402 error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str()); 1403 break; 1404 case eExecutionHitBreakpoint: 1405 error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str()); 1406 break; 1407 case eExecutionTimedOut: 1408 error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str()); 1409 break; 1410 } 1411 } 1412 } 1413 } 1414 } 1415 if (error.Fail()) 1416 break; 1417 } 1418 } 1419 return error; 1420 } 1421 1422 1423 bool 1424 CommandInterpreter::HandleCommand (const char *command_line, 1425 LazyBool lazy_add_to_history, 1426 CommandReturnObject &result, 1427 ExecutionContext *override_context, 1428 bool repeat_on_empty_command, 1429 bool no_context_switching) 1430 1431 { 1432 1433 bool done = false; 1434 CommandObject *cmd_obj = NULL; 1435 bool wants_raw_input = false; 1436 std::string command_string (command_line); 1437 std::string original_command_string (command_line); 1438 1439 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); 1440 Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line); 1441 1442 // Make a scoped cleanup object that will clear the crash description string 1443 // on exit of this function. 1444 lldb_utility::CleanUp <const char *> crash_description_cleanup(NULL, Host::SetCrashDescription); 1445 1446 if (log) 1447 log->Printf ("Processing command: %s", command_line); 1448 1449 Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line); 1450 1451 if (!no_context_switching) 1452 UpdateExecutionContext (override_context); 1453 1454 // <rdar://problem/11328896> 1455 bool add_to_history; 1456 if (lazy_add_to_history == eLazyBoolCalculate) 1457 add_to_history = (m_command_source_depth == 0); 1458 else 1459 add_to_history = (lazy_add_to_history == eLazyBoolYes); 1460 1461 bool empty_command = false; 1462 bool comment_command = false; 1463 if (command_string.empty()) 1464 empty_command = true; 1465 else 1466 { 1467 const char *k_space_characters = "\t\n\v\f\r "; 1468 1469 size_t non_space = command_string.find_first_not_of (k_space_characters); 1470 // Check for empty line or comment line (lines whose first 1471 // non-space character is the comment character for this interpreter) 1472 if (non_space == std::string::npos) 1473 empty_command = true; 1474 else if (command_string[non_space] == m_comment_char) 1475 comment_command = true; 1476 else if (command_string[non_space] == m_repeat_char) 1477 { 1478 const char *history_string = FindHistoryString (command_string.c_str() + non_space); 1479 if (history_string == NULL) 1480 { 1481 result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str()); 1482 result.SetStatus(eReturnStatusFailed); 1483 return false; 1484 } 1485 add_to_history = false; 1486 command_string = history_string; 1487 original_command_string = history_string; 1488 } 1489 } 1490 1491 if (empty_command) 1492 { 1493 if (repeat_on_empty_command) 1494 { 1495 if (m_command_history.empty()) 1496 { 1497 result.AppendError ("empty command"); 1498 result.SetStatus(eReturnStatusFailed); 1499 return false; 1500 } 1501 else 1502 { 1503 command_line = m_repeat_command.c_str(); 1504 command_string = command_line; 1505 original_command_string = command_line; 1506 if (m_repeat_command.empty()) 1507 { 1508 result.AppendErrorWithFormat("No auto repeat.\n"); 1509 result.SetStatus (eReturnStatusFailed); 1510 return false; 1511 } 1512 } 1513 add_to_history = false; 1514 } 1515 else 1516 { 1517 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1518 return true; 1519 } 1520 } 1521 else if (comment_command) 1522 { 1523 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1524 return true; 1525 } 1526 1527 1528 Error error (PreprocessCommand (command_string)); 1529 1530 if (error.Fail()) 1531 { 1532 result.AppendError (error.AsCString()); 1533 result.SetStatus(eReturnStatusFailed); 1534 return false; 1535 } 1536 // Phase 1. 1537 1538 // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object 1539 // is for the specified command, and whether or not it wants raw input. This gets complicated by the fact that 1540 // the user could have specified an alias, and in translating the alias there may also be command options and/or 1541 // even data (including raw text strings) that need to be found and inserted into the command line as part of 1542 // the translation. So this first step is plain look-up & replacement, resulting in three things: 1). the command 1543 // object whose Execute method will actually be called; 2). a revised command string, with all substitutions & 1544 // replacements taken care of; 3). whether or not the Execute function wants raw input or not. 1545 1546 StreamString revised_command_line; 1547 size_t actual_cmd_name_len = 0; 1548 std::string next_word; 1549 StringList matches; 1550 while (!done) 1551 { 1552 char quote_char = '\0'; 1553 std::string suffix; 1554 ExtractCommand (command_string, next_word, suffix, quote_char); 1555 if (cmd_obj == NULL) 1556 { 1557 if (AliasExists (next_word.c_str())) 1558 { 1559 std::string alias_result; 1560 cmd_obj = BuildAliasResult (next_word.c_str(), command_string, alias_result, result); 1561 revised_command_line.Printf ("%s", alias_result.c_str()); 1562 if (cmd_obj) 1563 { 1564 wants_raw_input = cmd_obj->WantsRawCommandString (); 1565 actual_cmd_name_len = strlen (cmd_obj->GetCommandName()); 1566 } 1567 } 1568 else 1569 { 1570 cmd_obj = GetCommandObject (next_word.c_str(), &matches); 1571 if (cmd_obj) 1572 { 1573 actual_cmd_name_len += next_word.length(); 1574 revised_command_line.Printf ("%s", next_word.c_str()); 1575 wants_raw_input = cmd_obj->WantsRawCommandString (); 1576 } 1577 else 1578 { 1579 revised_command_line.Printf ("%s", next_word.c_str()); 1580 } 1581 } 1582 } 1583 else 1584 { 1585 if (cmd_obj->IsMultiwordObject ()) 1586 { 1587 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str()); 1588 if (sub_cmd_obj) 1589 { 1590 actual_cmd_name_len += next_word.length() + 1; 1591 revised_command_line.Printf (" %s", next_word.c_str()); 1592 cmd_obj = sub_cmd_obj; 1593 wants_raw_input = cmd_obj->WantsRawCommandString (); 1594 } 1595 else 1596 { 1597 if (quote_char) 1598 revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); 1599 else 1600 revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str()); 1601 done = true; 1602 } 1603 } 1604 else 1605 { 1606 if (quote_char) 1607 revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); 1608 else 1609 revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str()); 1610 done = true; 1611 } 1612 } 1613 1614 if (cmd_obj == NULL) 1615 { 1616 const size_t num_matches = matches.GetSize(); 1617 if (matches.GetSize() > 1) { 1618 StreamString error_msg; 1619 error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str()); 1620 1621 for (uint32_t i = 0; i < num_matches; ++i) { 1622 error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i)); 1623 } 1624 result.AppendRawError (error_msg.GetString().c_str()); 1625 } else { 1626 // We didn't have only one match, otherwise we wouldn't get here. 1627 assert(num_matches == 0); 1628 result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str()); 1629 } 1630 result.SetStatus (eReturnStatusFailed); 1631 return false; 1632 } 1633 1634 if (cmd_obj->IsMultiwordObject ()) 1635 { 1636 if (!suffix.empty()) 1637 { 1638 1639 result.AppendErrorWithFormat ("multi-word commands ('%s') can't have shorthand suffixes: '%s'\n", 1640 next_word.c_str(), 1641 suffix.c_str()); 1642 result.SetStatus (eReturnStatusFailed); 1643 return false; 1644 } 1645 } 1646 else 1647 { 1648 // If we found a normal command, we are done 1649 done = true; 1650 if (!suffix.empty()) 1651 { 1652 switch (suffix[0]) 1653 { 1654 case '/': 1655 // GDB format suffixes 1656 { 1657 Options *command_options = cmd_obj->GetOptions(); 1658 if (command_options && command_options->SupportsLongOption("gdb-format")) 1659 { 1660 std::string gdb_format_option ("--gdb-format="); 1661 gdb_format_option += (suffix.c_str() + 1); 1662 1663 bool inserted = false; 1664 std::string &cmd = revised_command_line.GetString(); 1665 size_t arg_terminator_idx = FindArgumentTerminator (cmd); 1666 if (arg_terminator_idx != std::string::npos) 1667 { 1668 // Insert the gdb format option before the "--" that terminates options 1669 gdb_format_option.append(1,' '); 1670 cmd.insert(arg_terminator_idx, gdb_format_option); 1671 inserted = true; 1672 } 1673 1674 if (!inserted) 1675 revised_command_line.Printf (" %s", gdb_format_option.c_str()); 1676 1677 if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos) 1678 revised_command_line.PutCString (" --"); 1679 } 1680 else 1681 { 1682 result.AppendErrorWithFormat ("the '%s' command doesn't support the --gdb-format option\n", 1683 cmd_obj->GetCommandName()); 1684 result.SetStatus (eReturnStatusFailed); 1685 return false; 1686 } 1687 } 1688 break; 1689 1690 default: 1691 result.AppendErrorWithFormat ("unknown command shorthand suffix: '%s'\n", 1692 suffix.c_str()); 1693 result.SetStatus (eReturnStatusFailed); 1694 return false; 1695 1696 } 1697 } 1698 } 1699 if (command_string.length() == 0) 1700 done = true; 1701 1702 } 1703 1704 if (!command_string.empty()) 1705 revised_command_line.Printf (" %s", command_string.c_str()); 1706 1707 // End of Phase 1. 1708 // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command 1709 // specified was valid; revised_command_line contains the complete command line (including command name(s)), 1710 // fully translated with all substitutions & translations taken care of (still in raw text format); and 1711 // wants_raw_input specifies whether the Execute method expects raw input or not. 1712 1713 1714 if (log) 1715 { 1716 log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>"); 1717 log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData()); 1718 log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False"); 1719 } 1720 1721 // Phase 2. 1722 // Take care of things like setting up the history command & calling the appropriate Execute method on the 1723 // CommandObject, with the appropriate arguments. 1724 1725 if (cmd_obj != NULL) 1726 { 1727 if (add_to_history) 1728 { 1729 Args command_args (revised_command_line.GetData()); 1730 const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); 1731 if (repeat_command != NULL) 1732 m_repeat_command.assign(repeat_command); 1733 else 1734 m_repeat_command.assign(original_command_string.c_str()); 1735 1736 // Don't keep pushing the same command onto the history... 1737 if (m_command_history.empty() || m_command_history.back() != original_command_string) 1738 m_command_history.push_back (original_command_string); 1739 } 1740 1741 command_string = revised_command_line.GetData(); 1742 std::string command_name (cmd_obj->GetCommandName()); 1743 std::string remainder; 1744 if (actual_cmd_name_len < command_string.length()) 1745 remainder = command_string.substr (actual_cmd_name_len); // Note: 'actual_cmd_name_len' may be considerably shorter 1746 // than cmd_obj->GetCommandName(), because name completion 1747 // allows users to enter short versions of the names, 1748 // e.g. 'br s' for 'breakpoint set'. 1749 1750 // Remove any initial spaces 1751 std::string white_space (" \t\v"); 1752 size_t pos = remainder.find_first_not_of (white_space); 1753 if (pos != 0 && pos != std::string::npos) 1754 remainder.erase(0, pos); 1755 1756 if (log) 1757 log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str()); 1758 1759 cmd_obj->Execute (remainder.c_str(), result); 1760 } 1761 else 1762 { 1763 // We didn't find the first command object, so complete the first argument. 1764 Args command_args (revised_command_line.GetData()); 1765 StringList matches; 1766 int num_matches; 1767 int cursor_index = 0; 1768 int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); 1769 bool word_complete; 1770 num_matches = HandleCompletionMatches (command_args, 1771 cursor_index, 1772 cursor_char_position, 1773 0, 1774 -1, 1775 word_complete, 1776 matches); 1777 1778 if (num_matches > 0) 1779 { 1780 std::string error_msg; 1781 error_msg.assign ("ambiguous command '"); 1782 error_msg.append(command_args.GetArgumentAtIndex(0)); 1783 error_msg.append ("'."); 1784 1785 error_msg.append (" Possible completions:"); 1786 for (int i = 0; i < num_matches; i++) 1787 { 1788 error_msg.append ("\n\t"); 1789 error_msg.append (matches.GetStringAtIndex (i)); 1790 } 1791 error_msg.append ("\n"); 1792 result.AppendRawError (error_msg.c_str()); 1793 } 1794 else 1795 result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0)); 1796 1797 result.SetStatus (eReturnStatusFailed); 1798 } 1799 1800 if (log) 1801 log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed")); 1802 1803 return result.Succeeded(); 1804 } 1805 1806 int 1807 CommandInterpreter::HandleCompletionMatches (Args &parsed_line, 1808 int &cursor_index, 1809 int &cursor_char_position, 1810 int match_start_point, 1811 int max_return_elements, 1812 bool &word_complete, 1813 StringList &matches) 1814 { 1815 int num_command_matches = 0; 1816 bool look_for_subcommand = false; 1817 1818 // For any of the command completions a unique match will be a complete word. 1819 word_complete = true; 1820 1821 if (cursor_index == -1) 1822 { 1823 // We got nothing on the command line, so return the list of commands 1824 bool include_aliases = true; 1825 num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches); 1826 } 1827 else if (cursor_index == 0) 1828 { 1829 // The cursor is in the first argument, so just do a lookup in the dictionary. 1830 CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches); 1831 num_command_matches = matches.GetSize(); 1832 1833 if (num_command_matches == 1 1834 && cmd_obj && cmd_obj->IsMultiwordObject() 1835 && matches.GetStringAtIndex(0) != NULL 1836 && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0) 1837 { 1838 look_for_subcommand = true; 1839 num_command_matches = 0; 1840 matches.DeleteStringAtIndex(0); 1841 parsed_line.AppendArgument (""); 1842 cursor_index++; 1843 cursor_char_position = 0; 1844 } 1845 } 1846 1847 if (cursor_index > 0 || look_for_subcommand) 1848 { 1849 // We are completing further on into a commands arguments, so find the command and tell it 1850 // to complete the command. 1851 // First see if there is a matching initial command: 1852 CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0)); 1853 if (command_object == NULL) 1854 { 1855 return 0; 1856 } 1857 else 1858 { 1859 parsed_line.Shift(); 1860 cursor_index--; 1861 num_command_matches = command_object->HandleCompletion (parsed_line, 1862 cursor_index, 1863 cursor_char_position, 1864 match_start_point, 1865 max_return_elements, 1866 word_complete, 1867 matches); 1868 } 1869 } 1870 1871 return num_command_matches; 1872 1873 } 1874 1875 int 1876 CommandInterpreter::HandleCompletion (const char *current_line, 1877 const char *cursor, 1878 const char *last_char, 1879 int match_start_point, 1880 int max_return_elements, 1881 StringList &matches) 1882 { 1883 // We parse the argument up to the cursor, so the last argument in parsed_line is 1884 // the one containing the cursor, and the cursor is after the last character. 1885 1886 Args parsed_line(current_line, last_char - current_line); 1887 Args partial_parsed_line(current_line, cursor - current_line); 1888 1889 // Don't complete comments, and if the line we are completing is just the history repeat character, 1890 // substitute the appropriate history line. 1891 const char *first_arg = parsed_line.GetArgumentAtIndex(0); 1892 if (first_arg) 1893 { 1894 if (first_arg[0] == m_comment_char) 1895 return 0; 1896 else if (first_arg[0] == m_repeat_char) 1897 { 1898 const char *history_string = FindHistoryString (first_arg); 1899 if (history_string != NULL) 1900 { 1901 matches.Clear(); 1902 matches.InsertStringAtIndex(0, history_string); 1903 return -2; 1904 } 1905 else 1906 return 0; 1907 1908 } 1909 } 1910 1911 1912 int num_args = partial_parsed_line.GetArgumentCount(); 1913 int cursor_index = partial_parsed_line.GetArgumentCount() - 1; 1914 int cursor_char_position; 1915 1916 if (cursor_index == -1) 1917 cursor_char_position = 0; 1918 else 1919 cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index)); 1920 1921 if (cursor > current_line && cursor[-1] == ' ') 1922 { 1923 // We are just after a space. If we are in an argument, then we will continue 1924 // parsing, but if we are between arguments, then we have to complete whatever the next 1925 // element would be. 1926 // We can distinguish the two cases because if we are in an argument (e.g. because the space is 1927 // protected by a quote) then the space will also be in the parsed argument... 1928 1929 const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index); 1930 if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ') 1931 { 1932 parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '"'); 1933 cursor_index++; 1934 cursor_char_position = 0; 1935 } 1936 } 1937 1938 int num_command_matches; 1939 1940 matches.Clear(); 1941 1942 // Only max_return_elements == -1 is supported at present: 1943 assert (max_return_elements == -1); 1944 bool word_complete; 1945 num_command_matches = HandleCompletionMatches (parsed_line, 1946 cursor_index, 1947 cursor_char_position, 1948 match_start_point, 1949 max_return_elements, 1950 word_complete, 1951 matches); 1952 1953 if (num_command_matches <= 0) 1954 return num_command_matches; 1955 1956 if (num_args == 0) 1957 { 1958 // If we got an empty string, insert nothing. 1959 matches.InsertStringAtIndex(0, ""); 1960 } 1961 else 1962 { 1963 // Now figure out if there is a common substring, and if so put that in element 0, otherwise 1964 // put an empty string in element 0. 1965 std::string command_partial_str; 1966 if (cursor_index >= 0) 1967 command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), 1968 parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position); 1969 1970 std::string common_prefix; 1971 matches.LongestCommonPrefix (common_prefix); 1972 const size_t partial_name_len = command_partial_str.size(); 1973 1974 // If we matched a unique single command, add a space... 1975 // Only do this if the completer told us this was a complete word, however... 1976 if (num_command_matches == 1 && word_complete) 1977 { 1978 char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index); 1979 if (quote_char != '\0') 1980 common_prefix.push_back(quote_char); 1981 1982 common_prefix.push_back(' '); 1983 } 1984 common_prefix.erase (0, partial_name_len); 1985 matches.InsertStringAtIndex(0, common_prefix.c_str()); 1986 } 1987 return num_command_matches; 1988 } 1989 1990 1991 CommandInterpreter::~CommandInterpreter () 1992 { 1993 } 1994 1995 const char * 1996 CommandInterpreter::GetPrompt () 1997 { 1998 return m_debugger.GetPrompt(); 1999 } 2000 2001 void 2002 CommandInterpreter::SetPrompt (const char *new_prompt) 2003 { 2004 m_debugger.SetPrompt (new_prompt); 2005 } 2006 2007 size_t 2008 CommandInterpreter::GetConfirmationInputReaderCallback 2009 ( 2010 void *baton, 2011 InputReader &reader, 2012 lldb::InputReaderAction action, 2013 const char *bytes, 2014 size_t bytes_len 2015 ) 2016 { 2017 File &out_file = reader.GetDebugger().GetOutputFile(); 2018 bool *response_ptr = (bool *) baton; 2019 2020 switch (action) 2021 { 2022 case eInputReaderActivate: 2023 if (out_file.IsValid()) 2024 { 2025 if (reader.GetPrompt()) 2026 { 2027 out_file.Printf ("%s", reader.GetPrompt()); 2028 out_file.Flush (); 2029 } 2030 } 2031 break; 2032 2033 case eInputReaderDeactivate: 2034 break; 2035 2036 case eInputReaderReactivate: 2037 if (out_file.IsValid() && reader.GetPrompt()) 2038 { 2039 out_file.Printf ("%s", reader.GetPrompt()); 2040 out_file.Flush (); 2041 } 2042 break; 2043 2044 case eInputReaderAsynchronousOutputWritten: 2045 break; 2046 2047 case eInputReaderGotToken: 2048 if (bytes_len == 0) 2049 { 2050 reader.SetIsDone(true); 2051 } 2052 else if (bytes[0] == 'y' || bytes[0] == 'Y') 2053 { 2054 *response_ptr = true; 2055 reader.SetIsDone(true); 2056 } 2057 else if (bytes[0] == 'n' || bytes[0] == 'N') 2058 { 2059 *response_ptr = false; 2060 reader.SetIsDone(true); 2061 } 2062 else 2063 { 2064 if (out_file.IsValid() && !reader.IsDone() && reader.GetPrompt()) 2065 { 2066 out_file.Printf ("Please answer \"y\" or \"n\".\n%s", reader.GetPrompt()); 2067 out_file.Flush (); 2068 } 2069 } 2070 break; 2071 2072 case eInputReaderInterrupt: 2073 case eInputReaderEndOfFile: 2074 *response_ptr = false; // Assume ^C or ^D means cancel the proposed action 2075 reader.SetIsDone (true); 2076 break; 2077 2078 case eInputReaderDone: 2079 break; 2080 } 2081 2082 return bytes_len; 2083 2084 } 2085 2086 bool 2087 CommandInterpreter::Confirm (const char *message, bool default_answer) 2088 { 2089 // Check AutoConfirm first: 2090 if (m_debugger.GetAutoConfirm()) 2091 return default_answer; 2092 2093 InputReaderSP reader_sp (new InputReader(GetDebugger())); 2094 bool response = default_answer; 2095 if (reader_sp) 2096 { 2097 std::string prompt(message); 2098 prompt.append(": ["); 2099 if (default_answer) 2100 prompt.append ("Y/n] "); 2101 else 2102 prompt.append ("y/N] "); 2103 2104 Error err (reader_sp->Initialize (CommandInterpreter::GetConfirmationInputReaderCallback, 2105 &response, // baton 2106 eInputReaderGranularityLine, // token size, to pass to callback function 2107 NULL, // end token 2108 prompt.c_str(), // prompt 2109 true)); // echo input 2110 if (err.Success()) 2111 { 2112 GetDebugger().PushInputReader (reader_sp); 2113 } 2114 reader_sp->WaitOnReaderIsDone(); 2115 } 2116 return response; 2117 } 2118 2119 2120 void 2121 CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type) 2122 { 2123 CommandObjectSP cmd_obj_sp = GetCommandSPExact (dest_cmd, true); 2124 2125 if (cmd_obj_sp) 2126 { 2127 CommandObject *cmd_obj = cmd_obj_sp.get(); 2128 if (cmd_obj->IsCrossRefObject ()) 2129 cmd_obj->AddObject (object_type); 2130 } 2131 } 2132 2133 OptionArgVectorSP 2134 CommandInterpreter::GetAliasOptions (const char *alias_name) 2135 { 2136 OptionArgMap::iterator pos; 2137 OptionArgVectorSP ret_val; 2138 2139 std::string alias (alias_name); 2140 2141 if (HasAliasOptions()) 2142 { 2143 pos = m_alias_options.find (alias); 2144 if (pos != m_alias_options.end()) 2145 ret_val = pos->second; 2146 } 2147 2148 return ret_val; 2149 } 2150 2151 void 2152 CommandInterpreter::RemoveAliasOptions (const char *alias_name) 2153 { 2154 OptionArgMap::iterator pos = m_alias_options.find(alias_name); 2155 if (pos != m_alias_options.end()) 2156 { 2157 m_alias_options.erase (pos); 2158 } 2159 } 2160 2161 void 2162 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp) 2163 { 2164 m_alias_options[alias_name] = option_arg_vector_sp; 2165 } 2166 2167 bool 2168 CommandInterpreter::HasCommands () 2169 { 2170 return (!m_command_dict.empty()); 2171 } 2172 2173 bool 2174 CommandInterpreter::HasAliases () 2175 { 2176 return (!m_alias_dict.empty()); 2177 } 2178 2179 bool 2180 CommandInterpreter::HasUserCommands () 2181 { 2182 return (!m_user_dict.empty()); 2183 } 2184 2185 bool 2186 CommandInterpreter::HasAliasOptions () 2187 { 2188 return (!m_alias_options.empty()); 2189 } 2190 2191 void 2192 CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj, 2193 const char *alias_name, 2194 Args &cmd_args, 2195 std::string &raw_input_string, 2196 CommandReturnObject &result) 2197 { 2198 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 2199 2200 bool wants_raw_input = alias_cmd_obj->WantsRawCommandString(); 2201 2202 // Make sure that the alias name is the 0th element in cmd_args 2203 std::string alias_name_str = alias_name; 2204 if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) 2205 cmd_args.Unshift (alias_name); 2206 2207 Args new_args (alias_cmd_obj->GetCommandName()); 2208 if (new_args.GetArgumentCount() == 2) 2209 new_args.Shift(); 2210 2211 if (option_arg_vector_sp.get()) 2212 { 2213 if (wants_raw_input) 2214 { 2215 // We have a command that both has command options and takes raw input. Make *sure* it has a 2216 // " -- " in the right place in the raw_input_string. 2217 size_t pos = raw_input_string.find(" -- "); 2218 if (pos == std::string::npos) 2219 { 2220 // None found; assume it goes at the beginning of the raw input string 2221 raw_input_string.insert (0, " -- "); 2222 } 2223 } 2224 2225 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 2226 const size_t old_size = cmd_args.GetArgumentCount(); 2227 std::vector<bool> used (old_size + 1, false); 2228 2229 used[0] = true; 2230 2231 for (int i = 0; i < option_arg_vector->size(); ++i) 2232 { 2233 OptionArgPair option_pair = (*option_arg_vector)[i]; 2234 OptionArgValue value_pair = option_pair.second; 2235 int value_type = value_pair.first; 2236 std::string option = option_pair.first; 2237 std::string value = value_pair.second; 2238 if (option.compare ("<argument>") == 0) 2239 { 2240 if (!wants_raw_input 2241 || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice 2242 new_args.AppendArgument (value.c_str()); 2243 } 2244 else 2245 { 2246 if (value_type != optional_argument) 2247 new_args.AppendArgument (option.c_str()); 2248 if (value.compare ("<no-argument>") != 0) 2249 { 2250 int index = GetOptionArgumentPosition (value.c_str()); 2251 if (index == 0) 2252 { 2253 // value was NOT a positional argument; must be a real value 2254 if (value_type != optional_argument) 2255 new_args.AppendArgument (value.c_str()); 2256 else 2257 { 2258 char buffer[255]; 2259 ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str()); 2260 new_args.AppendArgument (buffer); 2261 } 2262 2263 } 2264 else if (index >= cmd_args.GetArgumentCount()) 2265 { 2266 result.AppendErrorWithFormat 2267 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 2268 index); 2269 result.SetStatus (eReturnStatusFailed); 2270 return; 2271 } 2272 else 2273 { 2274 // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string 2275 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 2276 if (strpos != std::string::npos) 2277 { 2278 raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index))); 2279 } 2280 2281 if (value_type != optional_argument) 2282 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); 2283 else 2284 { 2285 char buffer[255]; 2286 ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(), 2287 cmd_args.GetArgumentAtIndex (index)); 2288 new_args.AppendArgument (buffer); 2289 } 2290 used[index] = true; 2291 } 2292 } 2293 } 2294 } 2295 2296 for (int j = 0; j < cmd_args.GetArgumentCount(); ++j) 2297 { 2298 if (!used[j] && !wants_raw_input) 2299 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j)); 2300 } 2301 2302 cmd_args.Clear(); 2303 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 2304 } 2305 else 2306 { 2307 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2308 // This alias was not created with any options; nothing further needs to be done, unless it is a command that 2309 // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw 2310 // input string. 2311 if (wants_raw_input) 2312 { 2313 cmd_args.Clear(); 2314 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 2315 } 2316 return; 2317 } 2318 2319 result.SetStatus (eReturnStatusSuccessFinishNoResult); 2320 return; 2321 } 2322 2323 2324 int 2325 CommandInterpreter::GetOptionArgumentPosition (const char *in_string) 2326 { 2327 int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position 2328 // of zero. 2329 2330 char *cptr = (char *) in_string; 2331 2332 // Does it start with '%' 2333 if (cptr[0] == '%') 2334 { 2335 ++cptr; 2336 2337 // Is the rest of it entirely digits? 2338 if (isdigit (cptr[0])) 2339 { 2340 const char *start = cptr; 2341 while (isdigit (cptr[0])) 2342 ++cptr; 2343 2344 // We've gotten to the end of the digits; are we at the end of the string? 2345 if (cptr[0] == '\0') 2346 position = atoi (start); 2347 } 2348 } 2349 2350 return position; 2351 } 2352 2353 void 2354 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) 2355 { 2356 FileSpec init_file; 2357 if (in_cwd) 2358 { 2359 // In the current working directory we don't load any program specific 2360 // .lldbinit files, we only look for a "./.lldbinit" file. 2361 if (m_skip_lldbinit_files) 2362 return; 2363 2364 init_file.SetFile ("./.lldbinit", true); 2365 } 2366 else 2367 { 2368 // If we aren't looking in the current working directory we are looking 2369 // in the home directory. We will first see if there is an application 2370 // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a 2371 // "-" and the name of the program. If this file doesn't exist, we fall 2372 // back to just the "~/.lldbinit" file. We also obey any requests to not 2373 // load the init files. 2374 const char *init_file_path = "~/.lldbinit"; 2375 2376 if (m_skip_app_init_files == false) 2377 { 2378 FileSpec program_file_spec (Host::GetProgramFileSpec()); 2379 const char *program_name = program_file_spec.GetFilename().AsCString(); 2380 2381 if (program_name) 2382 { 2383 char program_init_file_name[PATH_MAX]; 2384 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path, program_name); 2385 init_file.SetFile (program_init_file_name, true); 2386 if (!init_file.Exists()) 2387 init_file.Clear(); 2388 } 2389 } 2390 2391 if (!init_file && !m_skip_lldbinit_files) 2392 init_file.SetFile (init_file_path, true); 2393 } 2394 2395 // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting 2396 // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details). 2397 2398 if (init_file.Exists()) 2399 { 2400 ExecutionContext *exe_ctx = NULL; // We don't have any context yet. 2401 bool stop_on_continue = true; 2402 bool stop_on_error = false; 2403 bool echo_commands = false; 2404 bool print_results = false; 2405 2406 HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, eLazyBoolNo, result); 2407 } 2408 else 2409 { 2410 // nothing to be done if the file doesn't exist 2411 result.SetStatus(eReturnStatusSuccessFinishNoResult); 2412 } 2413 } 2414 2415 PlatformSP 2416 CommandInterpreter::GetPlatform (bool prefer_target_platform) 2417 { 2418 PlatformSP platform_sp; 2419 if (prefer_target_platform) 2420 { 2421 ExecutionContext exe_ctx(GetExecutionContext()); 2422 Target *target = exe_ctx.GetTargetPtr(); 2423 if (target) 2424 platform_sp = target->GetPlatform(); 2425 } 2426 2427 if (!platform_sp) 2428 platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform(); 2429 return platform_sp; 2430 } 2431 2432 void 2433 CommandInterpreter::HandleCommands (const StringList &commands, 2434 ExecutionContext *override_context, 2435 bool stop_on_continue, 2436 bool stop_on_error, 2437 bool echo_commands, 2438 bool print_results, 2439 LazyBool add_to_history, 2440 CommandReturnObject &result) 2441 { 2442 size_t num_lines = commands.GetSize(); 2443 2444 // If we are going to continue past a "continue" then we need to run the commands synchronously. 2445 // Make sure you reset this value anywhere you return from the function. 2446 2447 bool old_async_execution = m_debugger.GetAsyncExecution(); 2448 2449 // If we've been given an execution context, set it at the start, but don't keep resetting it or we will 2450 // cause series of commands that change the context, then do an operation that relies on that context to fail. 2451 2452 if (override_context != NULL) 2453 UpdateExecutionContext (override_context); 2454 2455 if (!stop_on_continue) 2456 { 2457 m_debugger.SetAsyncExecution (false); 2458 } 2459 2460 for (int idx = 0; idx < num_lines; idx++) 2461 { 2462 const char *cmd = commands.GetStringAtIndex(idx); 2463 if (cmd[0] == '\0') 2464 continue; 2465 2466 if (echo_commands) 2467 { 2468 result.AppendMessageWithFormat ("%s %s\n", 2469 GetPrompt(), 2470 cmd); 2471 } 2472 2473 CommandReturnObject tmp_result; 2474 // If override_context is not NULL, pass no_context_switching = true for 2475 // HandleCommand() since we updated our context already. 2476 bool success = HandleCommand(cmd, add_to_history, tmp_result, 2477 NULL, /* override_context */ 2478 true, /* repeat_on_empty_command */ 2479 override_context != NULL /* no_context_switching */); 2480 2481 if (print_results) 2482 { 2483 if (tmp_result.Succeeded()) 2484 result.AppendMessageWithFormat("%s", tmp_result.GetOutputData()); 2485 } 2486 2487 if (!success || !tmp_result.Succeeded()) 2488 { 2489 const char *error_msg = tmp_result.GetErrorData(); 2490 if (error_msg == NULL || error_msg[0] == '\0') 2491 error_msg = "<unknown error>.\n"; 2492 if (stop_on_error) 2493 { 2494 result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' failed with %s", 2495 idx, cmd, error_msg); 2496 result.SetStatus (eReturnStatusFailed); 2497 m_debugger.SetAsyncExecution (old_async_execution); 2498 return; 2499 } 2500 else if (print_results) 2501 { 2502 result.AppendMessageWithFormat ("Command #%d '%s' failed with %s", 2503 idx + 1, 2504 cmd, 2505 error_msg); 2506 } 2507 } 2508 2509 if (result.GetImmediateOutputStream()) 2510 result.GetImmediateOutputStream()->Flush(); 2511 2512 if (result.GetImmediateErrorStream()) 2513 result.GetImmediateErrorStream()->Flush(); 2514 2515 // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution 2516 // could be running (for instance in Breakpoint Commands. 2517 // So we check the return value to see if it is has running in it. 2518 if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult) 2519 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult)) 2520 { 2521 if (stop_on_continue) 2522 { 2523 // If we caused the target to proceed, and we're going to stop in that case, set the 2524 // status in our real result before returning. This is an error if the continue was not the 2525 // last command in the set of commands to be run. 2526 if (idx != num_lines - 1) 2527 result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' continued the target.\n", 2528 idx + 1, cmd); 2529 else 2530 result.AppendMessageWithFormat ("Command #%d '%s' continued the target.\n", idx + 1, cmd); 2531 2532 result.SetStatus(tmp_result.GetStatus()); 2533 m_debugger.SetAsyncExecution (old_async_execution); 2534 2535 return; 2536 } 2537 } 2538 2539 } 2540 2541 result.SetStatus (eReturnStatusSuccessFinishResult); 2542 m_debugger.SetAsyncExecution (old_async_execution); 2543 2544 return; 2545 } 2546 2547 void 2548 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, 2549 ExecutionContext *context, 2550 bool stop_on_continue, 2551 bool stop_on_error, 2552 bool echo_command, 2553 bool print_result, 2554 LazyBool add_to_history, 2555 CommandReturnObject &result) 2556 { 2557 if (cmd_file.Exists()) 2558 { 2559 bool success; 2560 StringList commands; 2561 success = commands.ReadFileLines(cmd_file); 2562 if (!success) 2563 { 2564 result.AppendErrorWithFormat ("Error reading commands from file: %s.\n", cmd_file.GetFilename().AsCString()); 2565 result.SetStatus (eReturnStatusFailed); 2566 return; 2567 } 2568 m_command_source_depth++; 2569 HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, add_to_history, result); 2570 m_command_source_depth--; 2571 } 2572 else 2573 { 2574 result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n", 2575 cmd_file.GetFilename().AsCString()); 2576 result.SetStatus (eReturnStatusFailed); 2577 return; 2578 } 2579 } 2580 2581 ScriptInterpreter * 2582 CommandInterpreter::GetScriptInterpreter (bool can_create) 2583 { 2584 if (m_script_interpreter_ap.get() != NULL) 2585 return m_script_interpreter_ap.get(); 2586 2587 if (!can_create) 2588 return NULL; 2589 2590 // <rdar://problem/11751427> 2591 // we need to protect the initialization of the script interpreter 2592 // otherwise we could end up with two threads both trying to create 2593 // their instance of it, and for some languages (e.g. Python) 2594 // this is a bulletproof recipe for disaster! 2595 // this needs to be a function-level static because multiple Debugger instances living in the same process 2596 // still need to be isolated and not try to initialize Python concurrently 2597 static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive); 2598 Mutex::Locker interpreter_lock(g_interpreter_mutex); 2599 2600 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 2601 if (log) 2602 log->Printf("Initializing the ScriptInterpreter now\n"); 2603 2604 lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage(); 2605 switch (script_lang) 2606 { 2607 case eScriptLanguagePython: 2608 #ifndef LLDB_DISABLE_PYTHON 2609 m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this)); 2610 break; 2611 #else 2612 // Fall through to the None case when python is disabled 2613 #endif 2614 case eScriptLanguageNone: 2615 m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this)); 2616 break; 2617 }; 2618 2619 return m_script_interpreter_ap.get(); 2620 } 2621 2622 2623 2624 bool 2625 CommandInterpreter::GetSynchronous () 2626 { 2627 return m_synchronous_execution; 2628 } 2629 2630 void 2631 CommandInterpreter::SetSynchronous (bool value) 2632 { 2633 m_synchronous_execution = value; 2634 } 2635 2636 void 2637 CommandInterpreter::OutputFormattedHelpText (Stream &strm, 2638 const char *word_text, 2639 const char *separator, 2640 const char *help_text, 2641 size_t max_word_len) 2642 { 2643 const uint32_t max_columns = m_debugger.GetTerminalWidth(); 2644 2645 int indent_size = max_word_len + strlen (separator) + 2; 2646 2647 strm.IndentMore (indent_size); 2648 2649 StreamString text_strm; 2650 text_strm.Printf ("%-*s %s %s", (int)max_word_len, word_text, separator, help_text); 2651 2652 size_t len = text_strm.GetSize(); 2653 const char *text = text_strm.GetData(); 2654 if (text[len - 1] == '\n') 2655 { 2656 text_strm.EOL(); 2657 len = text_strm.GetSize(); 2658 } 2659 2660 if (len < max_columns) 2661 { 2662 // Output it as a single line. 2663 strm.Printf ("%s", text); 2664 } 2665 else 2666 { 2667 // We need to break it up into multiple lines. 2668 bool first_line = true; 2669 int text_width; 2670 size_t start = 0; 2671 size_t end = start; 2672 const size_t final_end = strlen (text); 2673 2674 while (end < final_end) 2675 { 2676 if (first_line) 2677 text_width = max_columns - 1; 2678 else 2679 text_width = max_columns - indent_size - 1; 2680 2681 // Don't start the 'text' on a space, since we're already outputting the indentation. 2682 if (!first_line) 2683 { 2684 while ((start < final_end) && (text[start] == ' ')) 2685 start++; 2686 } 2687 2688 end = start + text_width; 2689 if (end > final_end) 2690 end = final_end; 2691 else 2692 { 2693 // If we're not at the end of the text, make sure we break the line on white space. 2694 while (end > start 2695 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') 2696 end--; 2697 assert (end > 0); 2698 } 2699 2700 const size_t sub_len = end - start; 2701 if (start != 0) 2702 strm.EOL(); 2703 if (!first_line) 2704 strm.Indent(); 2705 else 2706 first_line = false; 2707 assert (start <= final_end); 2708 assert (start + sub_len <= final_end); 2709 if (sub_len > 0) 2710 strm.Write (text + start, sub_len); 2711 start = end + 1; 2712 } 2713 } 2714 strm.EOL(); 2715 strm.IndentLess(indent_size); 2716 } 2717 2718 void 2719 CommandInterpreter::OutputHelpText (Stream &strm, 2720 const char *word_text, 2721 const char *separator, 2722 const char *help_text, 2723 uint32_t max_word_len) 2724 { 2725 int indent_size = max_word_len + strlen (separator) + 2; 2726 2727 strm.IndentMore (indent_size); 2728 2729 StreamString text_strm; 2730 text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text); 2731 2732 const uint32_t max_columns = m_debugger.GetTerminalWidth(); 2733 2734 size_t len = text_strm.GetSize(); 2735 const char *text = text_strm.GetData(); 2736 2737 uint32_t chars_left = max_columns; 2738 2739 for (uint32_t i = 0; i < len; i++) 2740 { 2741 if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n') 2742 { 2743 chars_left = max_columns - indent_size; 2744 strm.EOL(); 2745 strm.Indent(); 2746 } 2747 else 2748 { 2749 strm.PutChar(text[i]); 2750 chars_left--; 2751 } 2752 2753 } 2754 2755 strm.EOL(); 2756 strm.IndentLess(indent_size); 2757 } 2758 2759 void 2760 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found, 2761 StringList &commands_help) 2762 { 2763 CommandObject::CommandMap::const_iterator pos; 2764 2765 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 2766 { 2767 const char *command_name = pos->first.c_str(); 2768 CommandObject *cmd_obj = pos->second.get(); 2769 2770 if (cmd_obj->HelpTextContainsWord (search_word)) 2771 { 2772 commands_found.AppendString (command_name); 2773 commands_help.AppendString (cmd_obj->GetHelp()); 2774 } 2775 2776 if (cmd_obj->IsMultiwordObject()) 2777 cmd_obj->AproposAllSubCommands (command_name, 2778 search_word, 2779 commands_found, 2780 commands_help); 2781 2782 } 2783 } 2784 2785 2786 void 2787 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context) 2788 { 2789 if (override_context != NULL) 2790 { 2791 m_exe_ctx_ref = *override_context; 2792 } 2793 else 2794 { 2795 const bool adopt_selected = true; 2796 m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected); 2797 } 2798 } 2799 2800 void 2801 CommandInterpreter::DumpHistory (Stream &stream, uint32_t count) const 2802 { 2803 DumpHistory (stream, 0, count - 1); 2804 } 2805 2806 void 2807 CommandInterpreter::DumpHistory (Stream &stream, uint32_t start, uint32_t end) const 2808 { 2809 const size_t last_idx = std::min<size_t>(m_command_history.size(), end + 1); 2810 for (size_t i = start; i < last_idx; i++) 2811 { 2812 if (!m_command_history[i].empty()) 2813 { 2814 stream.Indent(); 2815 stream.Printf ("%4zu: %s\n", i, m_command_history[i].c_str()); 2816 } 2817 } 2818 } 2819 2820 const char * 2821 CommandInterpreter::FindHistoryString (const char *input_str) const 2822 { 2823 if (input_str[0] != m_repeat_char) 2824 return NULL; 2825 if (input_str[1] == '-') 2826 { 2827 bool success; 2828 size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success); 2829 if (!success) 2830 return NULL; 2831 if (idx > m_command_history.size()) 2832 return NULL; 2833 idx = m_command_history.size() - idx; 2834 return m_command_history[idx].c_str(); 2835 2836 } 2837 else if (input_str[1] == m_repeat_char) 2838 { 2839 if (m_command_history.empty()) 2840 return NULL; 2841 else 2842 return m_command_history.back().c_str(); 2843 } 2844 else 2845 { 2846 bool success; 2847 uint32_t idx = Args::StringToUInt32 (input_str+1, 0, 0, &success); 2848 if (!success) 2849 return NULL; 2850 if (idx >= m_command_history.size()) 2851 return NULL; 2852 return m_command_history[idx].c_str(); 2853 } 2854 } 2855