1254721Semaste//===-- CommandObject.cpp ---------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Interpreter/CommandObject.h" 11254721Semaste 12254721Semaste#include <string> 13288943Sdim#include <sstream> 14254721Semaste#include <map> 15254721Semaste 16254721Semaste#include <stdlib.h> 17254721Semaste#include <ctype.h> 18254721Semaste 19254721Semaste#include "lldb/Core/Address.h" 20254721Semaste#include "lldb/Core/ArchSpec.h" 21254721Semaste#include "lldb/Interpreter/Options.h" 22254721Semaste 23254721Semaste// These are for the Sourcename completers. 24254721Semaste// FIXME: Make a separate file for the completers. 25254721Semaste#include "lldb/Host/FileSpec.h" 26254721Semaste#include "lldb/Core/FileSpecList.h" 27288943Sdim#include "lldb/DataFormatters/FormatManager.h" 28254721Semaste#include "lldb/Target/Process.h" 29254721Semaste#include "lldb/Target/Target.h" 30254721Semaste 31296417Sdim#include "lldb/Target/Language.h" 32296417Sdim 33254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 34254721Semaste#include "lldb/Interpreter/CommandReturnObject.h" 35254721Semaste 36254721Semasteusing namespace lldb; 37254721Semasteusing namespace lldb_private; 38254721Semaste 39254721Semaste//------------------------------------------------------------------------- 40254721Semaste// CommandObject 41254721Semaste//------------------------------------------------------------------------- 42254721Semaste 43254721SemasteCommandObject::CommandObject 44254721Semaste( 45254721Semaste CommandInterpreter &interpreter, 46254721Semaste const char *name, 47254721Semaste const char *help, 48254721Semaste const char *syntax, 49254721Semaste uint32_t flags 50254721Semaste) : 51254721Semaste m_interpreter (interpreter), 52280031Sdim m_cmd_name (name ? name : ""), 53254721Semaste m_cmd_help_short (), 54254721Semaste m_cmd_help_long (), 55254721Semaste m_cmd_syntax (), 56254721Semaste m_is_alias (false), 57254721Semaste m_flags (flags), 58254721Semaste m_arguments(), 59276479Sdim m_deprecated_command_override_callback (nullptr), 60276479Sdim m_command_override_callback (nullptr), 61276479Sdim m_command_override_baton (nullptr) 62254721Semaste{ 63254721Semaste if (help && help[0]) 64254721Semaste m_cmd_help_short = help; 65254721Semaste if (syntax && syntax[0]) 66254721Semaste m_cmd_syntax = syntax; 67254721Semaste} 68254721Semaste 69254721SemasteCommandObject::~CommandObject () 70254721Semaste{ 71254721Semaste} 72254721Semaste 73254721Semasteconst char * 74254721SemasteCommandObject::GetHelp () 75254721Semaste{ 76254721Semaste return m_cmd_help_short.c_str(); 77254721Semaste} 78254721Semaste 79254721Semasteconst char * 80254721SemasteCommandObject::GetHelpLong () 81254721Semaste{ 82254721Semaste return m_cmd_help_long.c_str(); 83254721Semaste} 84254721Semaste 85254721Semasteconst char * 86254721SemasteCommandObject::GetSyntax () 87254721Semaste{ 88254721Semaste if (m_cmd_syntax.length() == 0) 89254721Semaste { 90254721Semaste StreamString syntax_str; 91254721Semaste syntax_str.Printf ("%s", GetCommandName()); 92276479Sdim if (GetOptions() != nullptr) 93254721Semaste syntax_str.Printf (" <cmd-options>"); 94254721Semaste if (m_arguments.size() > 0) 95254721Semaste { 96254721Semaste syntax_str.Printf (" "); 97254721Semaste if (WantsRawCommandString() && GetOptions() && GetOptions()->NumCommandOptions()) 98254721Semaste syntax_str.Printf("-- "); 99254721Semaste GetFormattedCommandArguments (syntax_str); 100254721Semaste } 101254721Semaste m_cmd_syntax = syntax_str.GetData (); 102254721Semaste } 103254721Semaste 104254721Semaste return m_cmd_syntax.c_str(); 105254721Semaste} 106254721Semaste 107254721Semasteconst char * 108254721SemasteCommandObject::GetCommandName () 109254721Semaste{ 110254721Semaste return m_cmd_name.c_str(); 111254721Semaste} 112254721Semaste 113254721Semastevoid 114254721SemasteCommandObject::SetCommandName (const char *name) 115254721Semaste{ 116254721Semaste m_cmd_name = name; 117254721Semaste} 118254721Semaste 119254721Semastevoid 120254721SemasteCommandObject::SetHelp (const char *cstr) 121254721Semaste{ 122254721Semaste m_cmd_help_short = cstr; 123254721Semaste} 124254721Semaste 125254721Semastevoid 126288943SdimCommandObject::SetHelp (std::string str) 127288943Sdim{ 128288943Sdim m_cmd_help_short = str; 129288943Sdim} 130288943Sdim 131288943Sdimvoid 132254721SemasteCommandObject::SetHelpLong (const char *cstr) 133254721Semaste{ 134254721Semaste m_cmd_help_long = cstr; 135254721Semaste} 136254721Semaste 137254721Semastevoid 138254721SemasteCommandObject::SetHelpLong (std::string str) 139254721Semaste{ 140254721Semaste m_cmd_help_long = str; 141254721Semaste} 142254721Semaste 143254721Semastevoid 144254721SemasteCommandObject::SetSyntax (const char *cstr) 145254721Semaste{ 146254721Semaste m_cmd_syntax = cstr; 147254721Semaste} 148254721Semaste 149254721SemasteOptions * 150254721SemasteCommandObject::GetOptions () 151254721Semaste{ 152254721Semaste // By default commands don't have options unless this virtual function 153254721Semaste // is overridden by base classes. 154276479Sdim return nullptr; 155254721Semaste} 156254721Semaste 157254721Semastebool 158254721SemasteCommandObject::ParseOptions 159254721Semaste( 160254721Semaste Args& args, 161254721Semaste CommandReturnObject &result 162254721Semaste) 163254721Semaste{ 164254721Semaste // See if the subclass has options? 165254721Semaste Options *options = GetOptions(); 166276479Sdim if (options != nullptr) 167254721Semaste { 168254721Semaste Error error; 169254721Semaste options->NotifyOptionParsingStarting(); 170254721Semaste 171254721Semaste // ParseOptions calls getopt_long_only, which always skips the zero'th item in the array and starts at position 1, 172254721Semaste // so we need to push a dummy value into position zero. 173254721Semaste args.Unshift("dummy_string"); 174254721Semaste error = args.ParseOptions (*options); 175254721Semaste 176254721Semaste // The "dummy_string" will have already been removed by ParseOptions, 177254721Semaste // so no need to remove it. 178254721Semaste 179254721Semaste if (error.Success()) 180254721Semaste error = options->NotifyOptionParsingFinished(); 181254721Semaste 182254721Semaste if (error.Success()) 183254721Semaste { 184254721Semaste if (options->VerifyOptions (result)) 185254721Semaste return true; 186254721Semaste } 187254721Semaste else 188254721Semaste { 189254721Semaste const char *error_cstr = error.AsCString(); 190254721Semaste if (error_cstr) 191254721Semaste { 192254721Semaste // We got an error string, lets use that 193254721Semaste result.AppendError(error_cstr); 194254721Semaste } 195254721Semaste else 196254721Semaste { 197254721Semaste // No error string, output the usage information into result 198254721Semaste options->GenerateOptionUsage (result.GetErrorStream(), this); 199254721Semaste } 200254721Semaste } 201254721Semaste result.SetStatus (eReturnStatusFailed); 202254721Semaste return false; 203254721Semaste } 204254721Semaste return true; 205254721Semaste} 206254721Semaste 207254721Semaste 208254721Semaste 209254721Semastebool 210254721SemasteCommandObject::CheckRequirements (CommandReturnObject &result) 211254721Semaste{ 212254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 213254721Semaste // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx 214254721Semaste // has shared pointers to the target, process, thread and frame and we don't 215254721Semaste // want any CommandObject instances to keep any of these objects around 216254721Semaste // longer than for a single command. Every command should call 217254721Semaste // CommandObject::Cleanup() after it has completed 218254721Semaste assert (m_exe_ctx.GetTargetPtr() == NULL); 219254721Semaste assert (m_exe_ctx.GetProcessPtr() == NULL); 220254721Semaste assert (m_exe_ctx.GetThreadPtr() == NULL); 221254721Semaste assert (m_exe_ctx.GetFramePtr() == NULL); 222254721Semaste#endif 223254721Semaste 224254721Semaste // Lock down the interpreter's execution context prior to running the 225254721Semaste // command so we guarantee the selected target, process, thread and frame 226254721Semaste // can't go away during the execution 227254721Semaste m_exe_ctx = m_interpreter.GetExecutionContext(); 228254721Semaste 229254721Semaste const uint32_t flags = GetFlags().Get(); 230288943Sdim if (flags & (eCommandRequiresTarget | 231288943Sdim eCommandRequiresProcess | 232288943Sdim eCommandRequiresThread | 233288943Sdim eCommandRequiresFrame | 234288943Sdim eCommandTryTargetAPILock )) 235254721Semaste { 236254721Semaste 237288943Sdim if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope()) 238254721Semaste { 239254721Semaste result.AppendError (GetInvalidTargetDescription()); 240254721Semaste return false; 241254721Semaste } 242254721Semaste 243288943Sdim if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope()) 244254721Semaste { 245280031Sdim if (!m_exe_ctx.HasTargetScope()) 246280031Sdim result.AppendError (GetInvalidTargetDescription()); 247280031Sdim else 248280031Sdim result.AppendError (GetInvalidProcessDescription()); 249254721Semaste return false; 250254721Semaste } 251254721Semaste 252288943Sdim if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope()) 253254721Semaste { 254280031Sdim if (!m_exe_ctx.HasTargetScope()) 255280031Sdim result.AppendError (GetInvalidTargetDescription()); 256280031Sdim else if (!m_exe_ctx.HasProcessScope()) 257280031Sdim result.AppendError (GetInvalidProcessDescription()); 258280031Sdim else 259280031Sdim result.AppendError (GetInvalidThreadDescription()); 260254721Semaste return false; 261254721Semaste } 262254721Semaste 263288943Sdim if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope()) 264254721Semaste { 265280031Sdim if (!m_exe_ctx.HasTargetScope()) 266280031Sdim result.AppendError (GetInvalidTargetDescription()); 267280031Sdim else if (!m_exe_ctx.HasProcessScope()) 268280031Sdim result.AppendError (GetInvalidProcessDescription()); 269280031Sdim else if (!m_exe_ctx.HasThreadScope()) 270280031Sdim result.AppendError (GetInvalidThreadDescription()); 271280031Sdim else 272280031Sdim result.AppendError (GetInvalidFrameDescription()); 273254721Semaste return false; 274254721Semaste } 275254721Semaste 276288943Sdim if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr)) 277254721Semaste { 278254721Semaste result.AppendError (GetInvalidRegContextDescription()); 279254721Semaste return false; 280254721Semaste } 281254721Semaste 282288943Sdim if (flags & eCommandTryTargetAPILock) 283254721Semaste { 284254721Semaste Target *target = m_exe_ctx.GetTargetPtr(); 285254721Semaste if (target) 286262528Semaste m_api_locker.Lock (target->GetAPIMutex()); 287254721Semaste } 288254721Semaste } 289254721Semaste 290288943Sdim if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)) 291254721Semaste { 292254721Semaste Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 293276479Sdim if (process == nullptr) 294254721Semaste { 295254721Semaste // A process that is not running is considered paused. 296288943Sdim if (GetFlags().Test(eCommandProcessMustBeLaunched)) 297254721Semaste { 298254721Semaste result.AppendError ("Process must exist."); 299254721Semaste result.SetStatus (eReturnStatusFailed); 300254721Semaste return false; 301254721Semaste } 302254721Semaste } 303254721Semaste else 304254721Semaste { 305254721Semaste StateType state = process->GetState(); 306254721Semaste switch (state) 307254721Semaste { 308254721Semaste case eStateInvalid: 309254721Semaste case eStateSuspended: 310254721Semaste case eStateCrashed: 311254721Semaste case eStateStopped: 312254721Semaste break; 313254721Semaste 314254721Semaste case eStateConnected: 315254721Semaste case eStateAttaching: 316254721Semaste case eStateLaunching: 317254721Semaste case eStateDetached: 318254721Semaste case eStateExited: 319254721Semaste case eStateUnloaded: 320288943Sdim if (GetFlags().Test(eCommandProcessMustBeLaunched)) 321254721Semaste { 322254721Semaste result.AppendError ("Process must be launched."); 323254721Semaste result.SetStatus (eReturnStatusFailed); 324254721Semaste return false; 325254721Semaste } 326254721Semaste break; 327254721Semaste 328254721Semaste case eStateRunning: 329254721Semaste case eStateStepping: 330288943Sdim if (GetFlags().Test(eCommandProcessMustBePaused)) 331254721Semaste { 332254721Semaste result.AppendError ("Process is running. Use 'process interrupt' to pause execution."); 333254721Semaste result.SetStatus (eReturnStatusFailed); 334254721Semaste return false; 335254721Semaste } 336254721Semaste } 337254721Semaste } 338254721Semaste } 339254721Semaste return true; 340254721Semaste} 341254721Semaste 342254721Semastevoid 343254721SemasteCommandObject::Cleanup () 344254721Semaste{ 345254721Semaste m_exe_ctx.Clear(); 346254721Semaste m_api_locker.Unlock(); 347254721Semaste} 348254721Semaste 349254721Semaste 350254721Semasteclass CommandDictCommandPartialMatch 351254721Semaste{ 352254721Semaste public: 353254721Semaste CommandDictCommandPartialMatch (const char *match_str) 354254721Semaste { 355254721Semaste m_match_str = match_str; 356254721Semaste } 357254721Semaste bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const 358254721Semaste { 359254721Semaste // A NULL or empty string matches everything. 360276479Sdim if (m_match_str == nullptr || *m_match_str == '\0') 361254721Semaste return true; 362254721Semaste 363254721Semaste return map_element.first.find (m_match_str, 0) == 0; 364254721Semaste } 365254721Semaste 366254721Semaste private: 367254721Semaste const char *m_match_str; 368254721Semaste}; 369254721Semaste 370254721Semasteint 371254721SemasteCommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str, 372254721Semaste StringList &matches) 373254721Semaste{ 374254721Semaste int number_added = 0; 375254721Semaste CommandDictCommandPartialMatch matcher(cmd_str); 376254721Semaste 377254721Semaste CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher); 378254721Semaste 379254721Semaste while (matching_cmds != in_map.end()) 380254721Semaste { 381254721Semaste ++number_added; 382254721Semaste matches.AppendString((*matching_cmds).first.c_str()); 383254721Semaste matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);; 384254721Semaste } 385254721Semaste return number_added; 386254721Semaste} 387254721Semaste 388254721Semasteint 389254721SemasteCommandObject::HandleCompletion 390254721Semaste( 391254721Semaste Args &input, 392254721Semaste int &cursor_index, 393254721Semaste int &cursor_char_position, 394254721Semaste int match_start_point, 395254721Semaste int max_return_elements, 396254721Semaste bool &word_complete, 397254721Semaste StringList &matches 398254721Semaste) 399254721Semaste{ 400296417Sdim // Default implementation of WantsCompletion() is !WantsRawCommandString(). 401254721Semaste // Subclasses who want raw command string but desire, for example, 402254721Semaste // argument completion should override WantsCompletion() to return true, 403254721Semaste // instead. 404254721Semaste if (WantsRawCommandString() && !WantsCompletion()) 405254721Semaste { 406254721Semaste // FIXME: Abstract telling the completion to insert the completion character. 407254721Semaste matches.Clear(); 408254721Semaste return -1; 409254721Semaste } 410254721Semaste else 411254721Semaste { 412254721Semaste // Can we do anything generic with the options? 413254721Semaste Options *cur_options = GetOptions(); 414254721Semaste CommandReturnObject result; 415254721Semaste OptionElementVector opt_element_vector; 416254721Semaste 417276479Sdim if (cur_options != nullptr) 418254721Semaste { 419254721Semaste // Re-insert the dummy command name string which will have been 420254721Semaste // stripped off: 421254721Semaste input.Unshift ("dummy-string"); 422254721Semaste cursor_index++; 423254721Semaste 424254721Semaste 425254721Semaste // I stick an element on the end of the input, because if the last element is 426254721Semaste // option that requires an argument, getopt_long_only will freak out. 427254721Semaste 428254721Semaste input.AppendArgument ("<FAKE-VALUE>"); 429254721Semaste 430254721Semaste input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index); 431254721Semaste 432254721Semaste input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1); 433254721Semaste 434254721Semaste bool handled_by_options; 435254721Semaste handled_by_options = cur_options->HandleOptionCompletion (input, 436254721Semaste opt_element_vector, 437254721Semaste cursor_index, 438254721Semaste cursor_char_position, 439254721Semaste match_start_point, 440254721Semaste max_return_elements, 441254721Semaste word_complete, 442254721Semaste matches); 443254721Semaste if (handled_by_options) 444254721Semaste return matches.GetSize(); 445254721Semaste } 446254721Semaste 447254721Semaste // If we got here, the last word is not an option or an option argument. 448254721Semaste return HandleArgumentCompletion (input, 449254721Semaste cursor_index, 450254721Semaste cursor_char_position, 451254721Semaste opt_element_vector, 452254721Semaste match_start_point, 453254721Semaste max_return_elements, 454254721Semaste word_complete, 455254721Semaste matches); 456254721Semaste } 457254721Semaste} 458254721Semaste 459254721Semastebool 460254721SemasteCommandObject::HelpTextContainsWord (const char *search_word) 461254721Semaste{ 462254721Semaste std::string options_usage_help; 463254721Semaste 464254721Semaste bool found_word = false; 465254721Semaste 466254721Semaste const char *short_help = GetHelp(); 467254721Semaste const char *long_help = GetHelpLong(); 468254721Semaste const char *syntax_help = GetSyntax(); 469254721Semaste 470254721Semaste if (short_help && strcasestr (short_help, search_word)) 471254721Semaste found_word = true; 472254721Semaste else if (long_help && strcasestr (long_help, search_word)) 473254721Semaste found_word = true; 474254721Semaste else if (syntax_help && strcasestr (syntax_help, search_word)) 475254721Semaste found_word = true; 476254721Semaste 477254721Semaste if (!found_word 478276479Sdim && GetOptions() != nullptr) 479254721Semaste { 480254721Semaste StreamString usage_help; 481254721Semaste GetOptions()->GenerateOptionUsage (usage_help, this); 482254721Semaste if (usage_help.GetSize() > 0) 483254721Semaste { 484254721Semaste const char *usage_text = usage_help.GetData(); 485254721Semaste if (strcasestr (usage_text, search_word)) 486254721Semaste found_word = true; 487254721Semaste } 488254721Semaste } 489254721Semaste 490254721Semaste return found_word; 491254721Semaste} 492254721Semaste 493254721Semasteint 494254721SemasteCommandObject::GetNumArgumentEntries () 495254721Semaste{ 496254721Semaste return m_arguments.size(); 497254721Semaste} 498254721Semaste 499254721SemasteCommandObject::CommandArgumentEntry * 500254721SemasteCommandObject::GetArgumentEntryAtIndex (int idx) 501254721Semaste{ 502276479Sdim if (static_cast<size_t>(idx) < m_arguments.size()) 503254721Semaste return &(m_arguments[idx]); 504254721Semaste 505276479Sdim return nullptr; 506254721Semaste} 507254721Semaste 508288943Sdimconst CommandObject::ArgumentTableEntry * 509254721SemasteCommandObject::FindArgumentDataByType (CommandArgumentType arg_type) 510254721Semaste{ 511254721Semaste const ArgumentTableEntry *table = CommandObject::GetArgumentTable(); 512254721Semaste 513254721Semaste for (int i = 0; i < eArgTypeLastArg; ++i) 514254721Semaste if (table[i].arg_type == arg_type) 515288943Sdim return &(table[i]); 516254721Semaste 517276479Sdim return nullptr; 518254721Semaste} 519254721Semaste 520254721Semastevoid 521254721SemasteCommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter) 522254721Semaste{ 523254721Semaste const ArgumentTableEntry* table = CommandObject::GetArgumentTable(); 524288943Sdim const ArgumentTableEntry *entry = &(table[arg_type]); 525254721Semaste 526254721Semaste // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up... 527254721Semaste 528254721Semaste if (entry->arg_type != arg_type) 529254721Semaste entry = CommandObject::FindArgumentDataByType (arg_type); 530254721Semaste 531254721Semaste if (!entry) 532254721Semaste return; 533254721Semaste 534254721Semaste StreamString name_str; 535254721Semaste name_str.Printf ("<%s>", entry->arg_name); 536254721Semaste 537254721Semaste if (entry->help_function) 538254721Semaste { 539254721Semaste const char* help_text = entry->help_function(); 540254721Semaste if (!entry->help_function.self_formatting) 541254721Semaste { 542254721Semaste interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text, 543254721Semaste name_str.GetSize()); 544254721Semaste } 545254721Semaste else 546254721Semaste { 547254721Semaste interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text, 548254721Semaste name_str.GetSize()); 549254721Semaste } 550254721Semaste } 551254721Semaste else 552254721Semaste interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize()); 553254721Semaste} 554254721Semaste 555254721Semasteconst char * 556254721SemasteCommandObject::GetArgumentName (CommandArgumentType arg_type) 557254721Semaste{ 558288943Sdim const ArgumentTableEntry *entry = &(CommandObject::GetArgumentTable()[arg_type]); 559254721Semaste 560254721Semaste // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up... 561254721Semaste 562254721Semaste if (entry->arg_type != arg_type) 563254721Semaste entry = CommandObject::FindArgumentDataByType (arg_type); 564254721Semaste 565254721Semaste if (entry) 566254721Semaste return entry->arg_name; 567254721Semaste 568254721Semaste StreamString str; 569254721Semaste str << "Arg name for type (" << arg_type << ") not in arg table!"; 570254721Semaste return str.GetData(); 571254721Semaste} 572254721Semaste 573254721Semastebool 574254721SemasteCommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type) 575254721Semaste{ 576254721Semaste if ((arg_repeat_type == eArgRepeatPairPlain) 577254721Semaste || (arg_repeat_type == eArgRepeatPairOptional) 578254721Semaste || (arg_repeat_type == eArgRepeatPairPlus) 579254721Semaste || (arg_repeat_type == eArgRepeatPairStar) 580254721Semaste || (arg_repeat_type == eArgRepeatPairRange) 581254721Semaste || (arg_repeat_type == eArgRepeatPairRangeOptional)) 582254721Semaste return true; 583254721Semaste 584254721Semaste return false; 585254721Semaste} 586254721Semaste 587254721Semastestatic CommandObject::CommandArgumentEntry 588254721SemasteOptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry) 589254721Semaste{ 590254721Semaste CommandObject::CommandArgumentEntry ret_val; 591254721Semaste for (unsigned i = 0; i < cmd_arg_entry.size(); ++i) 592254721Semaste if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association) 593254721Semaste ret_val.push_back(cmd_arg_entry[i]); 594254721Semaste return ret_val; 595254721Semaste} 596254721Semaste 597254721Semaste// Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take 598254721Semaste// all the argument data into account. On rare cases where some argument sticks 599254721Semaste// with certain option sets, this function returns the option set filtered args. 600254721Semastevoid 601254721SemasteCommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask) 602254721Semaste{ 603254721Semaste int num_args = m_arguments.size(); 604254721Semaste for (int i = 0; i < num_args; ++i) 605254721Semaste { 606254721Semaste if (i > 0) 607254721Semaste str.Printf (" "); 608254721Semaste CommandArgumentEntry arg_entry = 609254721Semaste opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i] 610254721Semaste : OptSetFiltered(opt_set_mask, m_arguments[i]); 611254721Semaste int num_alternatives = arg_entry.size(); 612254721Semaste 613254721Semaste if ((num_alternatives == 2) 614254721Semaste && IsPairType (arg_entry[0].arg_repetition)) 615254721Semaste { 616254721Semaste const char *first_name = GetArgumentName (arg_entry[0].arg_type); 617254721Semaste const char *second_name = GetArgumentName (arg_entry[1].arg_type); 618254721Semaste switch (arg_entry[0].arg_repetition) 619254721Semaste { 620254721Semaste case eArgRepeatPairPlain: 621254721Semaste str.Printf ("<%s> <%s>", first_name, second_name); 622254721Semaste break; 623254721Semaste case eArgRepeatPairOptional: 624254721Semaste str.Printf ("[<%s> <%s>]", first_name, second_name); 625254721Semaste break; 626254721Semaste case eArgRepeatPairPlus: 627254721Semaste str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name); 628254721Semaste break; 629254721Semaste case eArgRepeatPairStar: 630254721Semaste str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name); 631254721Semaste break; 632254721Semaste case eArgRepeatPairRange: 633254721Semaste str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name); 634254721Semaste break; 635254721Semaste case eArgRepeatPairRangeOptional: 636254721Semaste str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name); 637254721Semaste break; 638254721Semaste // Explicitly test for all the rest of the cases, so if new types get added we will notice the 639254721Semaste // missing case statement(s). 640254721Semaste case eArgRepeatPlain: 641254721Semaste case eArgRepeatOptional: 642254721Semaste case eArgRepeatPlus: 643254721Semaste case eArgRepeatStar: 644254721Semaste case eArgRepeatRange: 645254721Semaste // These should not be reached, as they should fail the IsPairType test above. 646254721Semaste break; 647254721Semaste } 648254721Semaste } 649254721Semaste else 650254721Semaste { 651254721Semaste StreamString names; 652254721Semaste for (int j = 0; j < num_alternatives; ++j) 653254721Semaste { 654254721Semaste if (j > 0) 655254721Semaste names.Printf (" | "); 656254721Semaste names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type)); 657254721Semaste } 658254721Semaste switch (arg_entry[0].arg_repetition) 659254721Semaste { 660254721Semaste case eArgRepeatPlain: 661254721Semaste str.Printf ("<%s>", names.GetData()); 662254721Semaste break; 663254721Semaste case eArgRepeatPlus: 664254721Semaste str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData()); 665254721Semaste break; 666254721Semaste case eArgRepeatStar: 667254721Semaste str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData()); 668254721Semaste break; 669254721Semaste case eArgRepeatOptional: 670254721Semaste str.Printf ("[<%s>]", names.GetData()); 671254721Semaste break; 672254721Semaste case eArgRepeatRange: 673254721Semaste str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData()); 674254721Semaste break; 675254721Semaste // Explicitly test for all the rest of the cases, so if new types get added we will notice the 676254721Semaste // missing case statement(s). 677254721Semaste case eArgRepeatPairPlain: 678254721Semaste case eArgRepeatPairOptional: 679254721Semaste case eArgRepeatPairPlus: 680254721Semaste case eArgRepeatPairStar: 681254721Semaste case eArgRepeatPairRange: 682254721Semaste case eArgRepeatPairRangeOptional: 683254721Semaste // These should not be hit, as they should pass the IsPairType test above, and control should 684254721Semaste // have gone into the other branch of the if statement. 685254721Semaste break; 686254721Semaste } 687254721Semaste } 688254721Semaste } 689254721Semaste} 690254721Semaste 691254721SemasteCommandArgumentType 692254721SemasteCommandObject::LookupArgumentName (const char *arg_name) 693254721Semaste{ 694254721Semaste CommandArgumentType return_type = eArgTypeLastArg; 695254721Semaste 696254721Semaste std::string arg_name_str (arg_name); 697254721Semaste size_t len = arg_name_str.length(); 698254721Semaste if (arg_name[0] == '<' 699254721Semaste && arg_name[len-1] == '>') 700254721Semaste arg_name_str = arg_name_str.substr (1, len-2); 701254721Semaste 702254721Semaste const ArgumentTableEntry *table = GetArgumentTable(); 703254721Semaste for (int i = 0; i < eArgTypeLastArg; ++i) 704254721Semaste if (arg_name_str.compare (table[i].arg_name) == 0) 705254721Semaste return_type = g_arguments_data[i].arg_type; 706254721Semaste 707254721Semaste return return_type; 708254721Semaste} 709254721Semaste 710254721Semastestatic const char * 711254721SemasteRegisterNameHelpTextCallback () 712254721Semaste{ 713254721Semaste return "Register names can be specified using the architecture specific names. " 714254721Semaste "They can also be specified using generic names. Not all generic entities have " 715254721Semaste "registers backing them on all architectures. When they don't the generic name " 716254721Semaste "will return an error.\n" 717254721Semaste "The generic names defined in lldb are:\n" 718254721Semaste "\n" 719254721Semaste "pc - program counter register\n" 720254721Semaste "ra - return address register\n" 721254721Semaste "fp - frame pointer register\n" 722254721Semaste "sp - stack pointer register\n" 723254721Semaste "flags - the flags register\n" 724254721Semaste "arg{1-6} - integer argument passing registers.\n"; 725254721Semaste} 726254721Semaste 727254721Semastestatic const char * 728254721SemasteBreakpointIDHelpTextCallback () 729254721Semaste{ 730254721Semaste return "Breakpoint ID's consist major and minor numbers; the major number " 731254721Semaste "corresponds to the single entity that was created with a 'breakpoint set' " 732254721Semaste "command; the minor numbers correspond to all the locations that were actually " 733254721Semaste "found/set based on the major breakpoint. A full breakpoint ID might look like " 734254721Semaste "3.14, meaning the 14th location set for the 3rd breakpoint. You can specify " 735254721Semaste "all the locations of a breakpoint by just indicating the major breakpoint " 736254721Semaste "number. A valid breakpoint id consists either of just the major id number, " 737254721Semaste "or the major number, a dot, and the location number (e.g. 3 or 3.2 could " 738254721Semaste "both be valid breakpoint ids)."; 739254721Semaste} 740254721Semaste 741254721Semastestatic const char * 742254721SemasteBreakpointIDRangeHelpTextCallback () 743254721Semaste{ 744254721Semaste return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. " 745254721Semaste "This can be done through several mechanisms. The easiest way is to just " 746254721Semaste "enter a space-separated list of breakpoint ids. To specify all the " 747254721Semaste "breakpoint locations under a major breakpoint, you can use the major " 748254721Semaste "breakpoint number followed by '.*', eg. '5.*' means all the locations under " 749254721Semaste "breakpoint 5. You can also indicate a range of breakpoints by using " 750254721Semaste "<start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a range can " 751254721Semaste "be any valid breakpoint ids. It is not legal, however, to specify a range " 752254721Semaste "using specific locations that cross major breakpoint numbers. I.e. 3.2 - 3.7" 753254721Semaste " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal."; 754254721Semaste} 755254721Semaste 756254721Semastestatic const char * 757280031SdimBreakpointNameHelpTextCallback () 758280031Sdim{ 759280031Sdim return "A name that can be added to a breakpoint when it is created, or later " 760280031Sdim "on with the \"breakpoint name add\" command. " 761280031Sdim "Breakpoint names can be used to specify breakpoints in all the places breakpoint ID's " 762280031Sdim "and breakpoint ID ranges can be used. As such they provide a convenient way to group breakpoints, " 763280031Sdim "and to operate on breakpoints you create without having to track the breakpoint number. " 764280031Sdim "Note, the attributes you set when using a breakpoint name in a breakpoint command don't " 765280031Sdim "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that name. Future breakpoints " 766280031Sdim "tagged with that name will not pick up the attributes previously given using that name. " 767280031Sdim "In order to distinguish breakpoint names from breakpoint ID's and ranges, " 768280031Sdim "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\". " 769280031Sdim "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations."; 770280031Sdim} 771280031Sdim 772280031Sdimstatic const char * 773254721SemasteGDBFormatHelpTextCallback () 774254721Semaste{ 775254721Semaste return "A GDB format consists of a repeat count, a format letter and a size letter. " 776254721Semaste "The repeat count is optional and defaults to 1. The format letter is optional " 777254721Semaste "and defaults to the previous format that was used. The size letter is optional " 778254721Semaste "and defaults to the previous size that was used.\n" 779254721Semaste "\n" 780254721Semaste "Format letters include:\n" 781254721Semaste "o - octal\n" 782254721Semaste "x - hexadecimal\n" 783254721Semaste "d - decimal\n" 784254721Semaste "u - unsigned decimal\n" 785254721Semaste "t - binary\n" 786254721Semaste "f - float\n" 787254721Semaste "a - address\n" 788254721Semaste "i - instruction\n" 789254721Semaste "c - char\n" 790254721Semaste "s - string\n" 791254721Semaste "T - OSType\n" 792254721Semaste "A - float as hex\n" 793254721Semaste "\n" 794254721Semaste "Size letters include:\n" 795254721Semaste "b - 1 byte (byte)\n" 796254721Semaste "h - 2 bytes (halfword)\n" 797254721Semaste "w - 4 bytes (word)\n" 798254721Semaste "g - 8 bytes (giant)\n" 799254721Semaste "\n" 800254721Semaste "Example formats:\n" 801254721Semaste "32xb - show 32 1 byte hexadecimal integer values\n" 802254721Semaste "16xh - show 16 2 byte hexadecimal integer values\n" 803254721Semaste "64 - show 64 2 byte hexadecimal integer values (format and size from the last format)\n" 804254721Semaste "dw - show 1 4 byte decimal integer value\n" 805254721Semaste ; 806254721Semaste} 807254721Semaste 808254721Semastestatic const char * 809254721SemasteFormatHelpTextCallback () 810254721Semaste{ 811254721Semaste 812276479Sdim static char* help_text_ptr = nullptr; 813254721Semaste 814254721Semaste if (help_text_ptr) 815254721Semaste return help_text_ptr; 816254721Semaste 817254721Semaste StreamString sstr; 818254721Semaste sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n"; 819254721Semaste for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1)) 820254721Semaste { 821254721Semaste if (f != eFormatDefault) 822254721Semaste sstr.PutChar('\n'); 823254721Semaste 824254721Semaste char format_char = FormatManager::GetFormatAsFormatChar(f); 825254721Semaste if (format_char) 826254721Semaste sstr.Printf("'%c' or ", format_char); 827254721Semaste 828254721Semaste sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f)); 829254721Semaste } 830254721Semaste 831254721Semaste sstr.Flush(); 832254721Semaste 833254721Semaste std::string data = sstr.GetString(); 834254721Semaste 835254721Semaste help_text_ptr = new char[data.length()+1]; 836254721Semaste 837254721Semaste data.copy(help_text_ptr, data.length()); 838254721Semaste 839254721Semaste return help_text_ptr; 840254721Semaste} 841254721Semaste 842254721Semastestatic const char * 843254721SemasteLanguageTypeHelpTextCallback () 844254721Semaste{ 845276479Sdim static char* help_text_ptr = nullptr; 846254721Semaste 847254721Semaste if (help_text_ptr) 848254721Semaste return help_text_ptr; 849254721Semaste 850254721Semaste StreamString sstr; 851254721Semaste sstr << "One of the following languages:\n"; 852288943Sdim 853296417Sdim Language::PrintAllLanguages(sstr, " ", "\n"); 854288943Sdim 855254721Semaste sstr.Flush(); 856254721Semaste 857254721Semaste std::string data = sstr.GetString(); 858254721Semaste 859254721Semaste help_text_ptr = new char[data.length()+1]; 860254721Semaste 861254721Semaste data.copy(help_text_ptr, data.length()); 862254721Semaste 863254721Semaste return help_text_ptr; 864254721Semaste} 865254721Semaste 866254721Semastestatic const char * 867254721SemasteSummaryStringHelpTextCallback() 868254721Semaste{ 869254721Semaste return 870254721Semaste "A summary string is a way to extract information from variables in order to present them using a summary.\n" 871254721Semaste "Summary strings contain static text, variables, scopes and control sequences:\n" 872254721Semaste " - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n" 873254721Semaste " - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n" 874254721Semaste " - Scopes are any sequence of text between { and }. Anything included in a scope will only appear in the output summary if there were no errors.\n" 875254721Semaste " - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n" 876254721Semaste "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n" 877254721Semaste "A variable is expanded by giving it a value other than its textual representation, and the way this is done depends on what comes after the ${ marker.\n" 878254721Semaste "The most common sequence if ${var followed by an expression path, which is the text one would type to access a member of an aggregate types, given a variable of that type" 879254721Semaste " (e.g. if type T has a member named x, which has a member named y, and if t is of type T, the expression path would be .x.y and the way to fit that into a summary string would be" 880254721Semaste " ${var.x.y}). You can also use ${*var followed by an expression path and in that case the object referred by the path will be dereferenced before being displayed." 881254721Semaste " If the object is not a pointer, doing so will cause an error. For additional details on expression paths, you can type 'help expr-path'. \n" 882254721Semaste "By default, summary strings attempt to display the summary for any variable they reference, and if that fails the value. If neither can be shown, nothing is displayed." 883254721Semaste "In a summary string, you can also use an array index [n], or a slice-like range [n-m]. This can have two different meanings depending on what kind of object the expression" 884254721Semaste " path refers to:\n" 885254721Semaste " - if it is a scalar type (any basic type like int, float, ...) the expression is a bitfield, i.e. the bits indicated by the indexing operator are extracted out of the number" 886254721Semaste " and displayed as an individual variable\n" 887254721Semaste " - if it is an array or pointer the array items indicated by the indexing operator are shown as the result of the variable. if the expression is an array, real array items are" 888254721Semaste " printed; if it is a pointer, the pointer-as-array syntax is used to obtain the values (this means, the latter case can have no range checking)\n" 889254721Semaste "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1.\n" 890254721Semaste "Additionally, a variable can contain an (optional) format code, as in ${var.x.y%code}, where code can be any of the valid formats described in 'help format', or one of the" 891254721Semaste " special symbols only allowed as part of a variable:\n" 892254721Semaste " %V: show the value of the object by default\n" 893254721Semaste " %S: show the summary of the object by default\n" 894254721Semaste " %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n" 895254721Semaste " %L: show the location of the object (memory address or a register name)\n" 896254721Semaste " %#: show the number of children of the object\n" 897254721Semaste " %T: show the type of the object\n" 898254721Semaste "Another variable that you can use in summary strings is ${svar . This sequence works exactly like ${var, including the fact that ${*svar is an allowed sequence, but uses" 899254721Semaste " the object's synthetic children provider instead of the actual objects. For instance, if you are using STL synthetic children providers, the following summary string would" 900254721Semaste " count the number of actual elements stored in an std::list:\n" 901254721Semaste "type summary add -s \"${svar%#}\" -x \"std::list<\""; 902254721Semaste} 903254721Semaste 904254721Semastestatic const char * 905254721SemasteExprPathHelpTextCallback() 906254721Semaste{ 907254721Semaste return 908254721Semaste "An expression path is the sequence of symbols that is used in C/C++ to access a member variable of an aggregate object (class).\n" 909254721Semaste "For instance, given a class:\n" 910254721Semaste " class foo {\n" 911254721Semaste " int a;\n" 912254721Semaste " int b; .\n" 913254721Semaste " foo* next;\n" 914254721Semaste " };\n" 915254721Semaste "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n" 916254721Semaste "Given that aFoo could just be any object of type foo, the string '.next->b' is the expression path, because it can be attached to any foo instance to achieve the effect.\n" 917254721Semaste "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n" 918254721Semaste "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n" 919254721Semaste "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n" 920254721Semaste "for objects of native types (int, float, char, ...) saying '[n-m]' as an expression path (where n and m are any positive integers, e.g. [3-5]) causes LLDB to extract" 921254721Semaste " bits n thru m from the value of the variable. If n == m, [n] is also allowed as a shortcut syntax. For arrays and pointers, expression paths can only contain one index" 922254721Semaste " and the meaning of the operation is the same as the one defined by C/C++ (item extraction). Some commands extend bitfield-like syntax for arrays and pointers with the" 923254721Semaste " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory)."; 924254721Semaste} 925254721Semaste 926254721Semastevoid 927288943SdimCommandObject::FormatLongHelpText (Stream &output_strm, const char *long_help) 928288943Sdim{ 929288943Sdim CommandInterpreter& interpreter = GetCommandInterpreter(); 930288943Sdim std::stringstream lineStream (long_help); 931288943Sdim std::string line; 932288943Sdim while (std::getline (lineStream, line)) { 933288943Sdim if (line.empty()) { 934288943Sdim output_strm << "\n"; 935288943Sdim continue; 936288943Sdim } 937288943Sdim size_t result = line.find_first_not_of (" \t"); 938288943Sdim if (result == std::string::npos) { 939288943Sdim result = 0; 940288943Sdim } 941288943Sdim std::string whitespace_prefix = line.substr (0, result); 942288943Sdim std::string remainder = line.substr (result); 943288943Sdim interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), remainder.c_str()); 944288943Sdim } 945288943Sdim} 946288943Sdim 947288943Sdimvoid 948254721SemasteCommandObject::GenerateHelpText (CommandReturnObject &result) 949254721Semaste{ 950254721Semaste GenerateHelpText(result.GetOutputStream()); 951254721Semaste 952254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 953254721Semaste} 954254721Semaste 955254721Semastevoid 956254721SemasteCommandObject::GenerateHelpText (Stream &output_strm) 957254721Semaste{ 958254721Semaste CommandInterpreter& interpreter = GetCommandInterpreter(); 959276479Sdim if (GetOptions() != nullptr) 960254721Semaste { 961254721Semaste if (WantsRawCommandString()) 962254721Semaste { 963254721Semaste std::string help_text (GetHelp()); 964254721Semaste help_text.append (" This command takes 'raw' input (no need to quote stuff)."); 965254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1); 966254721Semaste } 967254721Semaste else 968254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1); 969254721Semaste output_strm.Printf ("\nSyntax: %s\n", GetSyntax()); 970254721Semaste GetOptions()->GenerateOptionUsage (output_strm, this); 971254721Semaste const char *long_help = GetHelpLong(); 972276479Sdim if ((long_help != nullptr) 973254721Semaste && (strlen (long_help) > 0)) 974288943Sdim FormatLongHelpText (output_strm, long_help); 975254721Semaste if (WantsRawCommandString() && !WantsCompletion()) 976254721Semaste { 977254721Semaste // Emit the message about using ' -- ' between the end of the command options and the raw input 978254721Semaste // conditionally, i.e., only if the command object does not want completion. 979254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", 980254721Semaste "\nIMPORTANT NOTE: Because this command takes 'raw' input, if you use any command options" 981254721Semaste " you must use ' -- ' between the end of the command options and the beginning of the raw input.", 1); 982254721Semaste } 983254721Semaste else if (GetNumArgumentEntries() > 0 984254721Semaste && GetOptions() 985254721Semaste && GetOptions()->NumCommandOptions() > 0) 986254721Semaste { 987254721Semaste // Also emit a warning about using "--" in case you are using a command that takes options and arguments. 988254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", 989254721Semaste "\nThis command takes options and free-form arguments. If your arguments resemble" 990254721Semaste " option specifiers (i.e., they start with a - or --), you must use ' -- ' between" 991254721Semaste " the end of the command options and the beginning of the arguments.", 1); 992254721Semaste } 993254721Semaste } 994254721Semaste else if (IsMultiwordObject()) 995254721Semaste { 996254721Semaste if (WantsRawCommandString()) 997254721Semaste { 998254721Semaste std::string help_text (GetHelp()); 999254721Semaste help_text.append (" This command takes 'raw' input (no need to quote stuff)."); 1000254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1); 1001254721Semaste } 1002254721Semaste else 1003254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1); 1004254721Semaste GenerateHelpText (output_strm); 1005254721Semaste } 1006254721Semaste else 1007254721Semaste { 1008254721Semaste const char *long_help = GetHelpLong(); 1009276479Sdim if ((long_help != nullptr) 1010254721Semaste && (strlen (long_help) > 0)) 1011288943Sdim FormatLongHelpText (output_strm, long_help); 1012254721Semaste else if (WantsRawCommandString()) 1013254721Semaste { 1014254721Semaste std::string help_text (GetHelp()); 1015254721Semaste help_text.append (" This command takes 'raw' input (no need to quote stuff)."); 1016254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1); 1017254721Semaste } 1018254721Semaste else 1019254721Semaste interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1); 1020254721Semaste output_strm.Printf ("\nSyntax: %s\n", GetSyntax()); 1021254721Semaste } 1022254721Semaste} 1023254721Semaste 1024254721Semastevoid 1025254721SemasteCommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange) 1026254721Semaste{ 1027254721Semaste CommandArgumentData id_arg; 1028254721Semaste CommandArgumentData id_range_arg; 1029254721Semaste 1030254721Semaste // Create the first variant for the first (and only) argument for this command. 1031254721Semaste id_arg.arg_type = ID; 1032254721Semaste id_arg.arg_repetition = eArgRepeatOptional; 1033254721Semaste 1034254721Semaste // Create the second variant for the first (and only) argument for this command. 1035254721Semaste id_range_arg.arg_type = IDRange; 1036254721Semaste id_range_arg.arg_repetition = eArgRepeatOptional; 1037254721Semaste 1038254721Semaste // The first (and only) argument for this command could be either an id or an id_range. 1039254721Semaste // Push both variants into the entry for the first argument for this command. 1040254721Semaste arg.push_back(id_arg); 1041254721Semaste arg.push_back(id_range_arg); 1042254721Semaste} 1043254721Semaste 1044254721Semasteconst char * 1045254721SemasteCommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) 1046254721Semaste{ 1047288943Sdim assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentTypeAsCString"); 1048288943Sdim return g_arguments_data[arg_type].arg_name; 1049254721Semaste} 1050254721Semaste 1051254721Semasteconst char * 1052254721SemasteCommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) 1053254721Semaste{ 1054288943Sdim assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentDescriptionAsCString"); 1055288943Sdim return g_arguments_data[arg_type].help_text; 1056254721Semaste} 1057254721Semaste 1058280031SdimTarget * 1059280031SdimCommandObject::GetDummyTarget() 1060280031Sdim{ 1061280031Sdim return m_interpreter.GetDebugger().GetDummyTarget(); 1062280031Sdim} 1063280031Sdim 1064280031SdimTarget * 1065280031SdimCommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) 1066280031Sdim{ 1067280031Sdim return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy); 1068280031Sdim} 1069280031Sdim 1070254721Semastebool 1071254721SemasteCommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result) 1072254721Semaste{ 1073254721Semaste bool handled = false; 1074254721Semaste Args cmd_args (args_string); 1075276479Sdim if (HasOverrideCallback()) 1076254721Semaste { 1077254721Semaste Args full_args (GetCommandName ()); 1078254721Semaste full_args.AppendArguments(cmd_args); 1079276479Sdim handled = InvokeOverrideCallback (full_args.GetConstArgumentVector(), result); 1080254721Semaste } 1081254721Semaste if (!handled) 1082254721Semaste { 1083254721Semaste for (size_t i = 0; i < cmd_args.GetArgumentCount(); ++i) 1084254721Semaste { 1085254721Semaste const char *tmp_str = cmd_args.GetArgumentAtIndex (i); 1086254721Semaste if (tmp_str[0] == '`') // back-quote 1087254721Semaste cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str)); 1088254721Semaste } 1089254721Semaste 1090254721Semaste if (CheckRequirements(result)) 1091254721Semaste { 1092254721Semaste if (ParseOptions (cmd_args, result)) 1093254721Semaste { 1094254721Semaste // Call the command-specific version of 'Execute', passing it the already processed arguments. 1095254721Semaste handled = DoExecute (cmd_args, result); 1096254721Semaste } 1097254721Semaste } 1098254721Semaste 1099254721Semaste Cleanup(); 1100254721Semaste } 1101254721Semaste return handled; 1102254721Semaste} 1103254721Semaste 1104254721Semastebool 1105254721SemasteCommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result) 1106254721Semaste{ 1107254721Semaste bool handled = false; 1108276479Sdim if (HasOverrideCallback()) 1109254721Semaste { 1110254721Semaste std::string full_command (GetCommandName ()); 1111254721Semaste full_command += ' '; 1112254721Semaste full_command += args_string; 1113276479Sdim const char *argv[2] = { nullptr, nullptr }; 1114254721Semaste argv[0] = full_command.c_str(); 1115276479Sdim handled = InvokeOverrideCallback (argv, result); 1116254721Semaste } 1117254721Semaste if (!handled) 1118254721Semaste { 1119254721Semaste if (CheckRequirements(result)) 1120254721Semaste handled = DoExecute (args_string, result); 1121254721Semaste 1122254721Semaste Cleanup(); 1123254721Semaste } 1124254721Semaste return handled; 1125254721Semaste} 1126254721Semaste 1127254721Semastestatic 1128254721Semasteconst char *arch_helper() 1129254721Semaste{ 1130254721Semaste static StreamString g_archs_help; 1131254721Semaste if (g_archs_help.Empty()) 1132254721Semaste { 1133254721Semaste StringList archs; 1134276479Sdim ArchSpec::AutoComplete(nullptr, archs); 1135254721Semaste g_archs_help.Printf("These are the supported architecture names:\n"); 1136254721Semaste archs.Join("\n", g_archs_help); 1137254721Semaste } 1138254721Semaste return g_archs_help.GetData(); 1139254721Semaste} 1140254721Semaste 1141254721SemasteCommandObject::ArgumentTableEntry 1142254721SemasteCommandObject::g_arguments_data[] = 1143254721Semaste{ 1144276479Sdim { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid address in the target program's execution space." }, 1145276479Sdim { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "An expression that resolves to an address." }, 1146276479Sdim { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of an abbreviation (alias) for a debugger command." }, 1147276479Sdim { eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, { nullptr, false }, "Command options to be used as part of an alias (abbreviation) definition. (See 'help commands alias' for more information.)" }, 1148254721Semaste { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." }, 1149276479Sdim { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" }, 1150276479Sdim { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr }, 1151276479Sdim { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr }, 1152280031Sdim { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr }, 1153276479Sdim { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." }, 1154276479Sdim { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." }, 1155276479Sdim { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." }, 1156276479Sdim { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." }, 1157276479Sdim { eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { nullptr, false }, "A directory name." }, 1158276479Sdim { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { nullptr, false }, "A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \"att\" and \"intel\" for Intel targets" }, 1159276479Sdim { eArgTypeDescriptionVerbosity, "description-verbosity", CommandCompletions::eNoCompletion, { nullptr, false }, "How verbose the output of 'po' should be." }, 1160276479Sdim { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1161276479Sdim { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1162276479Sdim { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, nullptr }, 1163276479Sdim { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { nullptr, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" }, 1164276479Sdim { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "The name of a file (can include path)." }, 1165276479Sdim { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, nullptr }, 1166276479Sdim { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into a thread's list of frames." }, 1167276479Sdim { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1168276479Sdim { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function." }, 1169276479Sdim { eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function or symbol." }, 1170276479Sdim { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, nullptr }, 1171280031Sdim { eArgTypeHelpText, "help-text", CommandCompletions::eNoCompletion, { nullptr, false }, "Text to be used as help for some other entity in LLDB" }, 1172276479Sdim { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." }, 1173276479Sdim { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr }, 1174276479Sdim { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." }, 1175276479Sdim { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." }, 1176276479Sdim { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." }, 1177276479Sdim { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." }, 1178276479Sdim { eArgTypeName, "name", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1179276479Sdim { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1180276479Sdim { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of lines to use." }, 1181276479Sdim { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of items per line to display." }, 1182276479Sdim { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1183276479Sdim { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1184276479Sdim { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { nullptr, false }, "A command that is entered as a single line of text." }, 1185276479Sdim { eArgTypePath, "path", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "Path." }, 1186276479Sdim { eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as an octal number (e.g. 755)." }, 1187276479Sdim { eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as a string value (e.g. rw-r-xr--)." }, 1188276479Sdim { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { nullptr, false }, "The process ID number." }, 1189276479Sdim { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1190276479Sdim { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the process." }, 1191276479Sdim { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python class." }, 1192276479Sdim { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python function." }, 1193276479Sdim { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." }, 1194276479Sdim { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the thread queue." }, 1195276479Sdim { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, nullptr }, 1196276479Sdim { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A regular expression." }, 1197276479Sdim { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." }, 1198276479Sdim { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1199276479Sdim { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." }, 1200276479Sdim { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands. Currently only Python is valid." }, 1201276479Sdim { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "The word for which you wish to search for information about." }, 1202276479Sdim { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { nullptr, false }, "An Objective-C selector name." }, 1203276479Sdim { eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." }, 1204276479Sdim { eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, { nullptr, false }, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." }, 1205276479Sdim { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" }, 1206276479Sdim { eArgTypeSettingVariableName, "setting-variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable. Type 'settings list' to see a complete list of such variables." }, 1207276479Sdim { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a shared library." }, 1208276479Sdim { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { nullptr, false }, "The name of a source file.." }, 1209276479Sdim { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify a sort order when dumping lists." }, 1210276479Sdim { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1211276479Sdim { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, nullptr }, 1212276479Sdim { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { nullptr, false }, "Any symbol name (function name, variable, argument, etc.)" }, 1213276479Sdim { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Thread ID number." }, 1214276479Sdim { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into the process' list of threads." }, 1215276479Sdim { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The thread's name." }, 1216288943Sdim { eArgTypeTypeName, "type-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A type name." }, 1217276479Sdim { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." }, 1218276479Sdim { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." }, 1219276479Sdim { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a variable in your program." }, 1220276479Sdim { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { nullptr, false }, "A value could be anything, depending on where and how it is used." }, 1221276479Sdim { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1222276479Sdim { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { nullptr, false }, "No help available for this." }, 1223276479Sdim { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, { nullptr, false }, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." }, 1224276479Sdim { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." }, 1225276479Sdim { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." }, 1226276479Sdim { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." } 1227254721Semaste}; 1228254721Semaste 1229254721Semasteconst CommandObject::ArgumentTableEntry* 1230254721SemasteCommandObject::GetArgumentTable () 1231254721Semaste{ 1232254721Semaste // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration 1233254721Semaste assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg); 1234254721Semaste return CommandObject::g_arguments_data; 1235254721Semaste} 1236254721Semaste 1237254721Semaste 1238