130fdc8d8SChris Lattner //===-- CommandObject.cpp ---------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandObject.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner #include <string> 1330fdc8d8SChris Lattner #include <map> 1430fdc8d8SChris Lattner 1530fdc8d8SChris Lattner #include <getopt.h> 1630fdc8d8SChris Lattner #include <stdlib.h> 1730fdc8d8SChris Lattner #include <ctype.h> 1830fdc8d8SChris Lattner 1930fdc8d8SChris Lattner #include "lldb/Core/Address.h" 2040af72e1SJim Ingham #include "lldb/Interpreter/Options.h" 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner // These are for the Sourcename completers. 2330fdc8d8SChris Lattner // FIXME: Make a separate file for the completers. 2430fdc8d8SChris Lattner #include "lldb/Core/FileSpec.h" 2530fdc8d8SChris Lattner #include "lldb/Core/FileSpecList.h" 2630fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2730fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2830fdc8d8SChris Lattner 2930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 3030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 3130fdc8d8SChris Lattner #include "lldb/Interpreter/ScriptInterpreter.h" 3230fdc8d8SChris Lattner #include "lldb/Interpreter/ScriptInterpreterPython.h" 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner using namespace lldb; 3530fdc8d8SChris Lattner using namespace lldb_private; 3630fdc8d8SChris Lattner 3730fdc8d8SChris Lattner //------------------------------------------------------------------------- 3830fdc8d8SChris Lattner // CommandObject 3930fdc8d8SChris Lattner //------------------------------------------------------------------------- 4030fdc8d8SChris Lattner 4130fdc8d8SChris Lattner CommandObject::CommandObject (const char *name, const char *help, const char *syntax, uint32_t flags) : 4230fdc8d8SChris Lattner m_cmd_name (name), 4330fdc8d8SChris Lattner m_cmd_help_short (), 4430fdc8d8SChris Lattner m_cmd_help_long (), 4530fdc8d8SChris Lattner m_cmd_syntax (), 4630fdc8d8SChris Lattner m_flags (flags) 4730fdc8d8SChris Lattner { 4830fdc8d8SChris Lattner if (help && help[0]) 4930fdc8d8SChris Lattner m_cmd_help_short = help; 5030fdc8d8SChris Lattner if (syntax && syntax[0]) 5130fdc8d8SChris Lattner m_cmd_syntax = syntax; 5230fdc8d8SChris Lattner } 5330fdc8d8SChris Lattner 5430fdc8d8SChris Lattner CommandObject::~CommandObject () 5530fdc8d8SChris Lattner { 5630fdc8d8SChris Lattner } 5730fdc8d8SChris Lattner 5830fdc8d8SChris Lattner const char * 5930fdc8d8SChris Lattner CommandObject::GetHelp () 6030fdc8d8SChris Lattner { 6130fdc8d8SChris Lattner return m_cmd_help_short.c_str(); 6230fdc8d8SChris Lattner } 6330fdc8d8SChris Lattner 6430fdc8d8SChris Lattner const char * 6530fdc8d8SChris Lattner CommandObject::GetHelpLong () 6630fdc8d8SChris Lattner { 6730fdc8d8SChris Lattner return m_cmd_help_long.c_str(); 6830fdc8d8SChris Lattner } 6930fdc8d8SChris Lattner 7030fdc8d8SChris Lattner const char * 7130fdc8d8SChris Lattner CommandObject::GetSyntax () 7230fdc8d8SChris Lattner { 7330fdc8d8SChris Lattner return m_cmd_syntax.c_str(); 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner 7630fdc8d8SChris Lattner const char * 7730fdc8d8SChris Lattner CommandObject::Translate () 7830fdc8d8SChris Lattner { 7930fdc8d8SChris Lattner //return m_cmd_func_name.c_str(); 8030fdc8d8SChris Lattner return "This function is currently not implemented."; 8130fdc8d8SChris Lattner } 8230fdc8d8SChris Lattner 8330fdc8d8SChris Lattner const char * 8430fdc8d8SChris Lattner CommandObject::GetCommandName () 8530fdc8d8SChris Lattner { 8630fdc8d8SChris Lattner return m_cmd_name.c_str(); 8730fdc8d8SChris Lattner } 8830fdc8d8SChris Lattner 8930fdc8d8SChris Lattner void 9030fdc8d8SChris Lattner CommandObject::SetCommandName (const char *name) 9130fdc8d8SChris Lattner { 9230fdc8d8SChris Lattner m_cmd_name = name; 9330fdc8d8SChris Lattner } 9430fdc8d8SChris Lattner 9530fdc8d8SChris Lattner void 9630fdc8d8SChris Lattner CommandObject::SetHelp (const char *cstr) 9730fdc8d8SChris Lattner { 9830fdc8d8SChris Lattner m_cmd_help_short = cstr; 9930fdc8d8SChris Lattner } 10030fdc8d8SChris Lattner 10130fdc8d8SChris Lattner void 10230fdc8d8SChris Lattner CommandObject::SetHelpLong (const char *cstr) 10330fdc8d8SChris Lattner { 10430fdc8d8SChris Lattner m_cmd_help_long = cstr; 10530fdc8d8SChris Lattner } 10630fdc8d8SChris Lattner 10730fdc8d8SChris Lattner void 10830fdc8d8SChris Lattner CommandObject::SetSyntax (const char *cstr) 10930fdc8d8SChris Lattner { 11030fdc8d8SChris Lattner m_cmd_syntax = cstr; 11130fdc8d8SChris Lattner } 11230fdc8d8SChris Lattner 11330fdc8d8SChris Lattner Options * 11430fdc8d8SChris Lattner CommandObject::GetOptions () 11530fdc8d8SChris Lattner { 11630fdc8d8SChris Lattner // By default commands don't have options unless this virtual function 11730fdc8d8SChris Lattner // is overridden by base classes. 11830fdc8d8SChris Lattner return NULL; 11930fdc8d8SChris Lattner } 12030fdc8d8SChris Lattner 12130fdc8d8SChris Lattner Flags& 12230fdc8d8SChris Lattner CommandObject::GetFlags() 12330fdc8d8SChris Lattner { 12430fdc8d8SChris Lattner return m_flags; 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner 12730fdc8d8SChris Lattner const Flags& 12830fdc8d8SChris Lattner CommandObject::GetFlags() const 12930fdc8d8SChris Lattner { 13030fdc8d8SChris Lattner return m_flags; 13130fdc8d8SChris Lattner } 13230fdc8d8SChris Lattner 13330fdc8d8SChris Lattner bool 13430fdc8d8SChris Lattner CommandObject::ExecuteCommandString 13530fdc8d8SChris Lattner ( 1366611103cSGreg Clayton CommandInterpreter &interpreter, 13730fdc8d8SChris Lattner const char *command_line, 13830fdc8d8SChris Lattner CommandReturnObject &result 13930fdc8d8SChris Lattner ) 14030fdc8d8SChris Lattner { 14130fdc8d8SChris Lattner Args command_args(command_line); 1426611103cSGreg Clayton return ExecuteWithOptions (interpreter, command_args, result); 14330fdc8d8SChris Lattner } 14430fdc8d8SChris Lattner 14530fdc8d8SChris Lattner bool 14630fdc8d8SChris Lattner CommandObject::ParseOptions 14730fdc8d8SChris Lattner ( 1486611103cSGreg Clayton CommandInterpreter &interpreter, 14930fdc8d8SChris Lattner Args& args, 15030fdc8d8SChris Lattner CommandReturnObject &result 15130fdc8d8SChris Lattner ) 15230fdc8d8SChris Lattner { 15330fdc8d8SChris Lattner // See if the subclass has options? 15430fdc8d8SChris Lattner Options *options = GetOptions(); 15530fdc8d8SChris Lattner if (options != NULL) 15630fdc8d8SChris Lattner { 15730fdc8d8SChris Lattner Error error; 15830fdc8d8SChris Lattner options->ResetOptionValues(); 15930fdc8d8SChris Lattner 16030fdc8d8SChris Lattner // ParseOptions calls getopt_long, which always skips the zero'th item in the array and starts at position 1, 16130fdc8d8SChris Lattner // so we need to push a dummy value into position zero. 16230fdc8d8SChris Lattner args.Unshift("dummy_string"); 16330fdc8d8SChris Lattner error = args.ParseOptions (*options); 16430fdc8d8SChris Lattner 16530fdc8d8SChris Lattner // The "dummy_string" will have already been removed by ParseOptions, 16630fdc8d8SChris Lattner // so no need to remove it. 16730fdc8d8SChris Lattner 16830fdc8d8SChris Lattner if (error.Fail() || !options->VerifyOptions (result)) 16930fdc8d8SChris Lattner { 17030fdc8d8SChris Lattner const char *error_cstr = error.AsCString(); 17130fdc8d8SChris Lattner if (error_cstr) 17230fdc8d8SChris Lattner { 17330fdc8d8SChris Lattner // We got an error string, lets use that 17430fdc8d8SChris Lattner result.GetErrorStream().PutCString(error_cstr); 17530fdc8d8SChris Lattner } 17630fdc8d8SChris Lattner else 17730fdc8d8SChris Lattner { 17830fdc8d8SChris Lattner // No error string, output the usage information into result 17930fdc8d8SChris Lattner options->GenerateOptionUsage (result.GetErrorStream(), this); 18030fdc8d8SChris Lattner } 18130fdc8d8SChris Lattner // Set the return status to failed (this was an error). 18230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 18330fdc8d8SChris Lattner return false; 18430fdc8d8SChris Lattner } 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner return true; 18730fdc8d8SChris Lattner } 18830fdc8d8SChris Lattner bool 18930fdc8d8SChris Lattner CommandObject::ExecuteWithOptions 19030fdc8d8SChris Lattner ( 1916611103cSGreg Clayton CommandInterpreter &interpreter, 19230fdc8d8SChris Lattner Args& args, 19330fdc8d8SChris Lattner CommandReturnObject &result 19430fdc8d8SChris Lattner ) 19530fdc8d8SChris Lattner { 19630fdc8d8SChris Lattner for (size_t i = 0; i < args.GetArgumentCount(); ++i) 19730fdc8d8SChris Lattner { 19830fdc8d8SChris Lattner const char *tmp_str = args.GetArgumentAtIndex (i); 19930fdc8d8SChris Lattner if (tmp_str[0] == '`') // back-quote 2006611103cSGreg Clayton args.ReplaceArgumentAtIndex (i, interpreter.ProcessEmbeddedScriptCommands (tmp_str)); 20130fdc8d8SChris Lattner } 20230fdc8d8SChris Lattner 2036611103cSGreg Clayton Process *process = interpreter.GetDebugger().GetExecutionContext().process; 20430fdc8d8SChris Lattner if (process == NULL) 20530fdc8d8SChris Lattner { 20630fdc8d8SChris Lattner if (GetFlags().IsSet(CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused)) 20730fdc8d8SChris Lattner { 20830fdc8d8SChris Lattner result.AppendError ("Process must exist."); 20930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 21030fdc8d8SChris Lattner return false; 21130fdc8d8SChris Lattner } 21230fdc8d8SChris Lattner } 21330fdc8d8SChris Lattner else 21430fdc8d8SChris Lattner { 21530fdc8d8SChris Lattner StateType state = process->GetState(); 21630fdc8d8SChris Lattner 21730fdc8d8SChris Lattner switch (state) 21830fdc8d8SChris Lattner { 21930fdc8d8SChris Lattner 22030fdc8d8SChris Lattner case eStateAttaching: 22130fdc8d8SChris Lattner case eStateLaunching: 22230fdc8d8SChris Lattner case eStateSuspended: 22330fdc8d8SChris Lattner case eStateCrashed: 22430fdc8d8SChris Lattner case eStateStopped: 22530fdc8d8SChris Lattner break; 22630fdc8d8SChris Lattner 22730fdc8d8SChris Lattner case eStateDetached: 22830fdc8d8SChris Lattner case eStateExited: 22930fdc8d8SChris Lattner case eStateUnloaded: 23030fdc8d8SChris Lattner if (GetFlags().IsSet(CommandObject::eFlagProcessMustBeLaunched)) 23130fdc8d8SChris Lattner { 23230fdc8d8SChris Lattner result.AppendError ("Process must be launched."); 23330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 23430fdc8d8SChris Lattner return false; 23530fdc8d8SChris Lattner } 23630fdc8d8SChris Lattner break; 23730fdc8d8SChris Lattner 23830fdc8d8SChris Lattner case eStateRunning: 23930fdc8d8SChris Lattner case eStateStepping: 24030fdc8d8SChris Lattner if (GetFlags().IsSet(CommandObject::eFlagProcessMustBePaused)) 24130fdc8d8SChris Lattner { 24230fdc8d8SChris Lattner result.AppendError ("Process is running. Use 'process interrupt' to pause execution."); 24330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 24430fdc8d8SChris Lattner return false; 24530fdc8d8SChris Lattner } 24630fdc8d8SChris Lattner } 24730fdc8d8SChris Lattner } 24830fdc8d8SChris Lattner 2496611103cSGreg Clayton if (!ParseOptions (interpreter, args, result)) 25030fdc8d8SChris Lattner return false; 25130fdc8d8SChris Lattner 25230fdc8d8SChris Lattner // Call the command-specific version of 'Execute', passing it the already processed arguments. 2536611103cSGreg Clayton return Execute (interpreter, args, result); 25430fdc8d8SChris Lattner } 25530fdc8d8SChris Lattner 25630fdc8d8SChris Lattner class CommandDictCommandPartialMatch 25730fdc8d8SChris Lattner { 25830fdc8d8SChris Lattner public: 25930fdc8d8SChris Lattner CommandDictCommandPartialMatch (const char *match_str) 26030fdc8d8SChris Lattner { 26130fdc8d8SChris Lattner m_match_str = match_str; 26230fdc8d8SChris Lattner } 26330fdc8d8SChris Lattner bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const 26430fdc8d8SChris Lattner { 26530fdc8d8SChris Lattner // A NULL or empty string matches everything. 26630fdc8d8SChris Lattner if (m_match_str == NULL || *m_match_str == '\0') 26730fdc8d8SChris Lattner return 1; 26830fdc8d8SChris Lattner 26930fdc8d8SChris Lattner size_t found = map_element.first.find (m_match_str, 0); 27030fdc8d8SChris Lattner if (found == std::string::npos) 27130fdc8d8SChris Lattner return 0; 27230fdc8d8SChris Lattner else 27330fdc8d8SChris Lattner return found == 0; 27430fdc8d8SChris Lattner } 27530fdc8d8SChris Lattner 27630fdc8d8SChris Lattner private: 27730fdc8d8SChris Lattner const char *m_match_str; 27830fdc8d8SChris Lattner }; 27930fdc8d8SChris Lattner 28030fdc8d8SChris Lattner int 28130fdc8d8SChris Lattner CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str, 28230fdc8d8SChris Lattner StringList &matches) 28330fdc8d8SChris Lattner { 28430fdc8d8SChris Lattner int number_added = 0; 28530fdc8d8SChris Lattner CommandDictCommandPartialMatch matcher(cmd_str); 28630fdc8d8SChris Lattner 28730fdc8d8SChris Lattner CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher); 28830fdc8d8SChris Lattner 28930fdc8d8SChris Lattner while (matching_cmds != in_map.end()) 29030fdc8d8SChris Lattner { 29130fdc8d8SChris Lattner ++number_added; 29230fdc8d8SChris Lattner matches.AppendString((*matching_cmds).first.c_str()); 29330fdc8d8SChris Lattner matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);; 29430fdc8d8SChris Lattner } 29530fdc8d8SChris Lattner return number_added; 29630fdc8d8SChris Lattner } 29730fdc8d8SChris Lattner 29830fdc8d8SChris Lattner int 29930fdc8d8SChris Lattner CommandObject::HandleCompletion 30030fdc8d8SChris Lattner ( 3016611103cSGreg Clayton CommandInterpreter &interpreter, 30230fdc8d8SChris Lattner Args &input, 30330fdc8d8SChris Lattner int &cursor_index, 30430fdc8d8SChris Lattner int &cursor_char_position, 30530fdc8d8SChris Lattner int match_start_point, 30630fdc8d8SChris Lattner int max_return_elements, 307*558ce124SJim Ingham bool &word_complete, 30830fdc8d8SChris Lattner StringList &matches 30930fdc8d8SChris Lattner ) 31030fdc8d8SChris Lattner { 31130fdc8d8SChris Lattner if (WantsRawCommandString()) 31230fdc8d8SChris Lattner { 31330fdc8d8SChris Lattner // FIXME: Abstract telling the completion to insert the completion character. 31430fdc8d8SChris Lattner matches.Clear(); 31530fdc8d8SChris Lattner return -1; 31630fdc8d8SChris Lattner } 31730fdc8d8SChris Lattner else 31830fdc8d8SChris Lattner { 31930fdc8d8SChris Lattner // Can we do anything generic with the options? 32030fdc8d8SChris Lattner Options *cur_options = GetOptions(); 32130fdc8d8SChris Lattner CommandReturnObject result; 32230fdc8d8SChris Lattner OptionElementVector opt_element_vector; 32330fdc8d8SChris Lattner 32430fdc8d8SChris Lattner if (cur_options != NULL) 32530fdc8d8SChris Lattner { 32630fdc8d8SChris Lattner // Re-insert the dummy command name string which will have been 32730fdc8d8SChris Lattner // stripped off: 32830fdc8d8SChris Lattner input.Unshift ("dummy-string"); 32930fdc8d8SChris Lattner cursor_index++; 33030fdc8d8SChris Lattner 33130fdc8d8SChris Lattner 33230fdc8d8SChris Lattner // I stick an element on the end of the input, because if the last element is 33330fdc8d8SChris Lattner // option that requires an argument, getopt_long will freak out. 33430fdc8d8SChris Lattner 33530fdc8d8SChris Lattner input.AppendArgument ("<FAKE-VALUE>"); 33630fdc8d8SChris Lattner 337d43e0094SJim Ingham input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index); 33830fdc8d8SChris Lattner 33930fdc8d8SChris Lattner input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1); 34030fdc8d8SChris Lattner 34130fdc8d8SChris Lattner bool handled_by_options; 3426611103cSGreg Clayton handled_by_options = cur_options->HandleOptionCompletion (interpreter, 3436611103cSGreg Clayton input, 34430fdc8d8SChris Lattner opt_element_vector, 34530fdc8d8SChris Lattner cursor_index, 34630fdc8d8SChris Lattner cursor_char_position, 34730fdc8d8SChris Lattner match_start_point, 34830fdc8d8SChris Lattner max_return_elements, 349*558ce124SJim Ingham word_complete, 35030fdc8d8SChris Lattner matches); 35130fdc8d8SChris Lattner if (handled_by_options) 35230fdc8d8SChris Lattner return matches.GetSize(); 35330fdc8d8SChris Lattner } 35430fdc8d8SChris Lattner 35530fdc8d8SChris Lattner // If we got here, the last word is not an option or an option argument. 3566611103cSGreg Clayton return HandleArgumentCompletion (interpreter, 3576611103cSGreg Clayton input, 35830fdc8d8SChris Lattner cursor_index, 35930fdc8d8SChris Lattner cursor_char_position, 36030fdc8d8SChris Lattner opt_element_vector, 36130fdc8d8SChris Lattner match_start_point, 36230fdc8d8SChris Lattner max_return_elements, 363*558ce124SJim Ingham word_complete, 36430fdc8d8SChris Lattner matches); 36530fdc8d8SChris Lattner } 36630fdc8d8SChris Lattner } 36730fdc8d8SChris Lattner 36830fdc8d8SChris Lattner // Case insensitive version of ::strstr() 36930fdc8d8SChris Lattner // Returns true if s2 is contained within s1. 37030fdc8d8SChris Lattner 37130fdc8d8SChris Lattner static bool 37230fdc8d8SChris Lattner contains_string (const char *s1, const char *s2) 37330fdc8d8SChris Lattner { 37430fdc8d8SChris Lattner char *locase_s1 = (char *) malloc (strlen (s1) + 1); 37530fdc8d8SChris Lattner char *locase_s2 = (char *) malloc (strlen (s2) + 1); 37630fdc8d8SChris Lattner int i; 37730fdc8d8SChris Lattner for (i = 0; s1 && s1[i] != '\0'; i++) 37830fdc8d8SChris Lattner locase_s1[i] = ::tolower (s1[i]); 37930fdc8d8SChris Lattner locase_s1[i] = '\0'; 38030fdc8d8SChris Lattner for (i = 0; s2 && s2[i] != '\0'; i++) 38130fdc8d8SChris Lattner locase_s2[i] = ::tolower (s2[i]); 38230fdc8d8SChris Lattner locase_s2[i] = '\0'; 38330fdc8d8SChris Lattner 38430fdc8d8SChris Lattner const char *result = ::strstr (locase_s1, locase_s2); 38530fdc8d8SChris Lattner free (locase_s1); 38630fdc8d8SChris Lattner free (locase_s2); 38730fdc8d8SChris Lattner // 'result' points into freed memory - but we're not 38830fdc8d8SChris Lattner // deref'ing it so hopefully current/future compilers 38930fdc8d8SChris Lattner // won't complain.. 39030fdc8d8SChris Lattner 39130fdc8d8SChris Lattner if (result == NULL) 39230fdc8d8SChris Lattner return false; 39330fdc8d8SChris Lattner else 39430fdc8d8SChris Lattner return true; 39530fdc8d8SChris Lattner } 39630fdc8d8SChris Lattner 39730fdc8d8SChris Lattner bool 39830fdc8d8SChris Lattner CommandObject::HelpTextContainsWord (const char *search_word) 39930fdc8d8SChris Lattner { 40030fdc8d8SChris Lattner const char *short_help; 40130fdc8d8SChris Lattner const char *long_help; 40230fdc8d8SChris Lattner const char *syntax_help; 40330fdc8d8SChris Lattner std::string options_usage_help; 40430fdc8d8SChris Lattner 40530fdc8d8SChris Lattner 40630fdc8d8SChris Lattner bool found_word = false; 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner short_help = GetHelp(); 40930fdc8d8SChris Lattner long_help = GetHelpLong(); 41030fdc8d8SChris Lattner syntax_help = GetSyntax(); 41130fdc8d8SChris Lattner 41230fdc8d8SChris Lattner if (contains_string (short_help, search_word)) 41330fdc8d8SChris Lattner found_word = true; 41430fdc8d8SChris Lattner else if (contains_string (long_help, search_word)) 41530fdc8d8SChris Lattner found_word = true; 41630fdc8d8SChris Lattner else if (contains_string (syntax_help, search_word)) 41730fdc8d8SChris Lattner found_word = true; 41830fdc8d8SChris Lattner 41930fdc8d8SChris Lattner if (!found_word 42030fdc8d8SChris Lattner && GetOptions() != NULL) 42130fdc8d8SChris Lattner { 42230fdc8d8SChris Lattner StreamString usage_help; 42330fdc8d8SChris Lattner GetOptions()->GenerateOptionUsage (usage_help, this); 42430fdc8d8SChris Lattner if (usage_help.GetSize() > 0) 42530fdc8d8SChris Lattner { 42630fdc8d8SChris Lattner const char *usage_text = usage_help.GetData(); 42730fdc8d8SChris Lattner if (contains_string (usage_text, search_word)) 42830fdc8d8SChris Lattner found_word = true; 42930fdc8d8SChris Lattner } 43030fdc8d8SChris Lattner } 43130fdc8d8SChris Lattner 43230fdc8d8SChris Lattner return found_word; 43330fdc8d8SChris Lattner } 434