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