bool CommandObjectMultiword::Execute(const char *args_string, CommandReturnObject &result) { Args args(args_string); const size_t argc = args.GetArgumentCount(); if (argc == 0) { this->CommandObject::GenerateHelpText(result); } else { const char *sub_command = args.GetArgumentAtIndex(0); if (sub_command) { if (::strcasecmp(sub_command, "help") == 0) { this->CommandObject::GenerateHelpText(result); } else if (!m_subcommand_dict.empty()) { StringList matches; CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches); if (sub_cmd_obj != nullptr) { // Now call CommandObject::Execute to process and options in // 'rest_of_line'. From there // the command-specific version of Execute will be called, with the // processed arguments. args.Shift(); sub_cmd_obj->Execute(args_string, result); } else { std::string error_msg; const size_t num_subcmd_matches = matches.GetSize(); if (num_subcmd_matches > 0) error_msg.assign("ambiguous command "); else error_msg.assign("invalid command "); error_msg.append("'"); error_msg.append(GetCommandName()); error_msg.append(" "); error_msg.append(sub_command); error_msg.append("'."); if (num_subcmd_matches > 0) { error_msg.append(" Possible completions:"); for (size_t i = 0; i < num_subcmd_matches; i++) { error_msg.append("\n\t"); error_msg.append(matches.GetStringAtIndex(i)); } } error_msg.append("\n"); result.AppendRawError(error_msg.c_str()); result.SetStatus(eReturnStatusFailed); } } else { result.AppendErrorWithFormat("'%s' does not have any subcommands.\n", GetCommandName()); result.SetStatus(eReturnStatusFailed); } } } return result.Succeeded(); }
bool CommandInterpreter::HandleCommand ( const char *command_line, bool add_to_history, CommandReturnObject &result, ExecutionContext *override_context ) { // FIXME: there should probably be a mutex to make sure only one thread can // run the interpreter at a time. // TODO: this should be a logging channel in lldb. // if (DebugSelf()) // { // result.AppendMessageWithFormat ("Processing command: %s\n", command_line); // } m_debugger.UpdateExecutionContext (override_context); if (command_line == NULL || command_line[0] == '\0') { if (m_command_history.empty()) { result.AppendError ("empty command"); result.SetStatus(eReturnStatusFailed); return false; } else { command_line = m_repeat_command.c_str(); if (m_repeat_command.empty()) { result.AppendErrorWithFormat("No auto repeat.\n"); result.SetStatus (eReturnStatusFailed); return false; } } add_to_history = false; } Args command_args(command_line); if (command_args.GetArgumentCount() > 0) { const char *command_cstr = command_args.GetArgumentAtIndex(0); if (command_cstr) { // We're looking up the command object here. So first find an exact match to the // command in the commands. CommandObject *command_obj = GetCommandObject(command_cstr); if (command_obj != NULL) { if (command_obj->IsAlias()) { BuildAliasCommandArgs (command_obj, command_cstr, command_args, result); if (!result.Succeeded()) return false; } if (add_to_history) { const char *repeat_command = command_obj->GetRepeatCommand(command_args, 0); if (repeat_command != NULL) m_repeat_command.assign(repeat_command); else m_repeat_command.assign(command_line); m_command_history.push_back (command_line); } if (command_obj->WantsRawCommandString()) { const char *stripped_command = ::strstr (command_line, command_cstr); if (stripped_command) { stripped_command += strlen(command_cstr); while (isspace(*stripped_command)) ++stripped_command; command_obj->ExecuteRawCommandString (*this, stripped_command, result); } } else { // Remove the command from the args. command_args.Shift(); command_obj->ExecuteWithOptions (*this, command_args, result); } } else { // We didn't find the first command object, so complete the first argument. StringList matches; int num_matches; int cursor_index = 0; int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); bool word_complete; num_matches = HandleCompletionMatches (command_args, cursor_index, cursor_char_position, 0, -1, word_complete, matches); if (num_matches > 0) { std::string error_msg; error_msg.assign ("ambiguous command '"); error_msg.append(command_cstr); error_msg.append ("'."); error_msg.append (" Possible completions:"); for (int i = 0; i < num_matches; i++) { error_msg.append ("\n\t"); error_msg.append (matches.GetStringAtIndex (i)); } error_msg.append ("\n"); result.AppendRawError (error_msg.c_str(), error_msg.size()); } else result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_cstr); result.SetStatus (eReturnStatusFailed); } } } return result.Succeeded(); }