int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index, int &cursor_char_position, int match_start_point, int max_return_elements, bool &word_complete, StringList &matches) { // Any of the command matches will provide a complete word, otherwise the // individual // completers will override this. word_complete = true; const char *arg0 = input.GetArgumentAtIndex(0); if (cursor_index == 0) { AddNamesMatchingPartialString(m_subcommand_dict, arg0, matches); if (matches.GetSize() == 1 && matches.GetStringAtIndex(0) != nullptr && strcmp(arg0, matches.GetStringAtIndex(0)) == 0) { StringList temp_matches; CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches); if (cmd_obj != nullptr) { if (input.GetArgumentCount() == 1) { word_complete = true; } else { matches.DeleteStringAtIndex(0); input.Shift(); cursor_char_position = 0; input.AppendArgument(""); return cmd_obj->HandleCompletion( input, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } } } return matches.GetSize(); } else { CommandObject *sub_command_object = GetSubcommandObject(arg0, &matches); if (sub_command_object == nullptr) { return matches.GetSize(); } else { // Remove the one match that we got from calling GetSubcommandObject. matches.DeleteStringAtIndex(0); input.Shift(); cursor_index--; return sub_command_object->HandleCompletion( input, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } } }
virtual bool DoExecute (Args& args, CommandReturnObject &result) { if (args.GetArgumentCount() < 2) { result.AppendErrorWithFormat("%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); } else { std::string channel(args.GetArgumentAtIndex(0)); args.Shift (); // Shift off the channel char log_file[PATH_MAX]; if (m_options.log_file) m_options.log_file.GetPath(log_file, sizeof(log_file)); else log_file[0] = '\0'; bool success = m_interpreter.GetDebugger().EnableLog (channel.c_str(), args.GetConstArgumentVector(), log_file, m_options.log_options, result.GetErrorStream()); if (success) result.SetStatus (eReturnStatusSuccessFinishNoResult); else result.SetStatus (eReturnStatusFailed); } return result.Succeeded(); }
bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.empty()) { result.AppendErrorWithFormat( "%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); return false; } Log::Callbacks log_callbacks; const std::string channel = args.GetArgumentAtIndex(0); args.Shift(); // Shift off the channel if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) { log_callbacks.disable(args.GetConstArgumentVector(), &result.GetErrorStream()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else if (channel == "all") { Log::DisableAllLogChannels(&result.GetErrorStream()); } else { LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.data())); if (log_channel_sp) { log_channel_sp->Disable(args.GetConstArgumentVector(), &result.GetErrorStream()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.data()); } return result.Succeeded(); }
int CommandObjectHelp::HandleCompletion(Args &input, int &cursor_index, int &cursor_char_position, int match_start_point, int max_return_elements, bool &word_complete, StringList &matches) { // Return the completions of the commands in the help system: if (cursor_index == 0) { return m_interpreter.HandleCompletionMatches( input, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } else { CommandObject *cmd_obj = m_interpreter.GetCommandObject(input[0].ref); // The command that they are getting help on might be ambiguous, in which // case we should complete that, // otherwise complete with the command the user is getting help on... if (cmd_obj) { input.Shift(); cursor_index--; return cmd_obj->HandleCompletion( input, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } else { return m_interpreter.HandleCompletionMatches( input, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } } }
virtual bool Execute (Args& args, CommandReturnObject &result) { const size_t argc = args.GetArgumentCount(); if (argc == 0) { result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); } else { Log::Callbacks log_callbacks; std::string channel(args.GetArgumentAtIndex(0)); args.Shift (); // Shift off the channel if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks)) { log_callbacks.disable (args, &result.GetErrorStream()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else if (channel == "all") { Log::DisableAllLogChannels(&result.GetErrorStream()); } else { LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str())); if (log_channel_sp) { log_channel_sp->Disable(args, &result.GetErrorStream()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0)); } } return result.Succeeded(); }
int CommandObjectHelp::HandleCompletion ( Args &input, int &cursor_index, int &cursor_char_position, int match_start_point, int max_return_elements, bool &word_complete, StringList &matches ) { // Return the completions of the commands in the help system: if (cursor_index == 0) { return m_interpreter.HandleCompletionMatches (input, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } else { CommandObject *cmd_obj = m_interpreter.GetCommandObject (input.GetArgumentAtIndex(0)); input.Shift(); cursor_index--; return cmd_obj->HandleCompletion (input, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } }
int CommandInterpreter::HandleCompletionMatches (Args &parsed_line, int &cursor_index, int &cursor_char_position, int match_start_point, int max_return_elements, bool &word_complete, StringList &matches) { int num_command_matches = 0; bool look_for_subcommand = false; // For any of the command completions a unique match will be a complete word. word_complete = true; if (cursor_index == -1) { // We got nothing on the command line, so return the list of commands bool include_aliases = true; num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches); } else if (cursor_index == 0) { // The cursor is in the first argument, so just do a lookup in the dictionary. CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches); num_command_matches = matches.GetSize(); if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() && matches.GetStringAtIndex(0) != NULL && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0) { look_for_subcommand = true; num_command_matches = 0; matches.DeleteStringAtIndex(0); parsed_line.AppendArgument (""); cursor_index++; cursor_char_position = 0; } } if (cursor_index > 0 || look_for_subcommand) { // We are completing further on into a commands arguments, so find the command and tell it // to complete the command. // First see if there is a matching initial command: CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0)); if (command_object == NULL) { return 0; } else { parsed_line.Shift(); cursor_index--; num_command_matches = command_object->HandleCompletion (*this, parsed_line, cursor_index, cursor_char_position, match_start_point, max_return_elements, word_complete, matches); } } return num_command_matches; }
virtual bool Execute (Args& command, CommandReturnObject &result) { Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; if (process == NULL) { result.AppendError("need a process to read memory"); result.SetStatus(eReturnStatusFailed); return false; } const size_t argc = command.GetArgumentCount(); if (m_options.m_infile) { if (argc < 1) { result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } } else if (argc < 2) { result.AppendErrorWithFormat ("%s takes a destination address and at least one value.\n", m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } StreamString buffer (Stream::eBinary, process->GetTarget().GetArchitecture().GetAddressByteSize(), process->GetTarget().GetArchitecture().GetByteOrder()); size_t item_byte_size = m_options.m_byte_size; lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0); if (addr == LLDB_INVALID_ADDRESS) { result.AppendErrorWithFormat("Invalid address string '%s'.\n", command.GetArgumentAtIndex(0)); result.SetStatus(eReturnStatusFailed); return false; } if (m_options.m_infile) { size_t length = SIZE_MAX; if (m_options.m_byte_size > 0) length = m_options.m_byte_size; lldb::DataBufferSP data_sp (m_options.m_infile.ReadFileContents (m_options.m_infile_offset, length)); if (data_sp) { length = data_sp->GetByteSize(); if (length > 0) { Error error; size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error); if (bytes_written == length) { // All bytes written result.GetOutputStream().Printf("%zu bytes were written to 0x%llx\n", bytes_written, addr); result.SetStatus(eReturnStatusSuccessFinishResult); } else if (bytes_written > 0) { // Some byte written result.GetOutputStream().Printf("%zu bytes of %zu requested were written to 0x%llx\n", bytes_written, length, addr); result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString()); result.SetStatus(eReturnStatusFailed); } } } else { result.AppendErrorWithFormat ("Unable to read contents of file.\n"); result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } else if (m_options.m_byte_size == 0) { if (m_options.m_format == eFormatPointer) item_byte_size = buffer.GetAddressByteSize(); else item_byte_size = 1; } command.Shift(); // shift off the address argument uint64_t uval64; int64_t sval64; bool success = false; const uint32_t num_value_args = command.GetArgumentCount(); uint32_t i; for (i=0; i<num_value_args; ++i) { const char *value_str = command.GetArgumentAtIndex(i); switch (m_options.m_format) { case eFormatFloat: // TODO: add support for floats soon case eFormatCharPrintable: case eFormatBytesWithASCII: case eFormatComplex: case eFormatEnum: case eFormatUnicode16: case eFormatUnicode32: case eFormatVectorOfChar: case eFormatVectorOfSInt8: case eFormatVectorOfUInt8: case eFormatVectorOfSInt16: case eFormatVectorOfUInt16: case eFormatVectorOfSInt32: case eFormatVectorOfUInt32: case eFormatVectorOfSInt64: case eFormatVectorOfUInt64: case eFormatVectorOfFloat32: case eFormatVectorOfFloat64: case eFormatVectorOfUInt128: result.AppendError("unsupported format for writing memory"); result.SetStatus(eReturnStatusFailed); return false; case eFormatDefault: case eFormatBytes: case eFormatHex: case eFormatPointer: // Decode hex bytes uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success); if (!success) { result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str); result.SetStatus(eReturnStatusFailed); return false; } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64 (uval64, item_byte_size); break; case eFormatBoolean: uval64 = Args::StringToBoolean(value_str, false, &success); if (!success) { result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str); result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64 (uval64, item_byte_size); break; case eFormatBinary: uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success); if (!success) { result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str); result.SetStatus(eReturnStatusFailed); return false; } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64 (uval64, item_byte_size); break; case eFormatChar: case eFormatCString: if (value_str[0]) { size_t len = strlen (value_str); // Include the NULL for C strings... if (m_options.m_format == eFormatCString) ++len; Error error; if (process->WriteMemory (addr, value_str, len, error) == len) { addr += len; } else { result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString()); result.SetStatus(eReturnStatusFailed); return false; } } break; case eFormatDecimal: sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success); if (!success) { result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str); result.SetStatus(eReturnStatusFailed); return false; } else if (!SIntValueIsValidForSize (sval64, item_byte_size)) { result.AppendErrorWithFormat ("Value %lli is too large or small to fit in a %u byte signed integer value.\n", sval64, item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64 (sval64, item_byte_size); break; case eFormatUnsigned: uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success); if (!success) { result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str); result.SetStatus(eReturnStatusFailed); return false; } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { result.AppendErrorWithFormat ("Value %llu is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64 (uval64, item_byte_size); break; case eFormatOctal: uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success); if (!success) { result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str); result.SetStatus(eReturnStatusFailed); return false; } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { result.AppendErrorWithFormat ("Value %llo is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } buffer.PutMaxHex64 (uval64, item_byte_size); break; } } if (!buffer.GetString().empty()) { Error error; if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size()) return true; else { result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString()); result.SetStatus(eReturnStatusFailed); return false; } } return true; }
// int // HandleArgumentCompletion (Args &input, // int &cursor_index, // int &cursor_char_position, // OptionElementVector &opt_element_vector, // int match_start_point, // int max_return_elements, // bool &word_complete, // StringList &matches) // { // std::string completion_str (input.GetArgumentAtIndex(cursor_index)); // completion_str.erase (cursor_char_position); // // if (cursor_index == 1) // { // // // Log::AutoCompleteChannelName (completion_str.c_str(), matches); // } // return matches.GetSize(); // } // virtual bool Execute (Args& args, CommandReturnObject &result) { if (args.GetArgumentCount() < 1) { result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); } else { Log::Callbacks log_callbacks; std::string channel(args.GetArgumentAtIndex(0)); args.Shift (); // Shift off the channel StreamSP log_stream_sp; if (m_options.log_file.empty()) { log_stream_sp.reset(new StreamFile(m_interpreter.GetDebugger().GetOutputFile().GetDescriptor(), false)); } else { LogStreamMap::iterator pos = m_log_streams.find(m_options.log_file); if (pos == m_log_streams.end()) { log_stream_sp.reset (new StreamFile (m_options.log_file.c_str())); m_log_streams[m_options.log_file] = log_stream_sp; } else log_stream_sp = pos->second; } assert (log_stream_sp.get()); uint32_t log_options = m_options.log_options; if (log_options == 0) log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks)) { log_callbacks.enable (log_stream_sp, log_options, args, &result.GetErrorStream()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel.c_str())); if (log_channel_sp) { if (log_channel_sp->Enable (log_stream_sp, log_options, &result.GetErrorStream(), args)) { result.SetStatus (eReturnStatusSuccessFinishNoResult); } else { result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str()); result.SetStatus (eReturnStatusFailed); } } else { result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str()); result.SetStatus (eReturnStatusFailed); } } } return result.Succeeded(); }