CommandObjectRegexCommand.cpp revision 341825
1254721Semaste//===-- CommandObjectRegexCommand.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/CommandObjectRegexCommand.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 17254721Semaste#include "lldb/Interpreter/CommandReturnObject.h" 18254721Semaste 19254721Semasteusing namespace lldb; 20254721Semasteusing namespace lldb_private; 21254721Semaste 22254721Semaste//---------------------------------------------------------------------- 23254721Semaste// CommandObjectRegexCommand constructor 24254721Semaste//---------------------------------------------------------------------- 25314564SdimCommandObjectRegexCommand::CommandObjectRegexCommand( 26314564Sdim CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help, 27314564Sdim llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask, 28314564Sdim bool is_removable) 29314564Sdim : CommandObjectRaw(interpreter, name, help, syntax), 30314564Sdim m_max_matches(max_matches), m_completion_type_mask(completion_type_mask), 31314564Sdim m_entries(), m_is_removable(is_removable) {} 32254721Semaste 33254721Semaste//---------------------------------------------------------------------- 34254721Semaste// Destructor 35254721Semaste//---------------------------------------------------------------------- 36314564SdimCommandObjectRegexCommand::~CommandObjectRegexCommand() {} 37254721Semaste 38341825Sdimbool CommandObjectRegexCommand::DoExecute(llvm::StringRef command, 39314564Sdim CommandReturnObject &result) { 40341825Sdim EntryCollection::const_iterator pos, end = m_entries.end(); 41341825Sdim for (pos = m_entries.begin(); pos != end; ++pos) { 42341825Sdim RegularExpression::Match regex_match(m_max_matches); 43254721Semaste 44341825Sdim if (pos->regex.Execute(command, ®ex_match)) { 45341825Sdim std::string new_command(pos->command); 46341825Sdim std::string match_str; 47341825Sdim char percent_var[8]; 48341825Sdim size_t idx, percent_var_idx; 49341825Sdim for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) { 50341825Sdim if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) { 51341825Sdim const int percent_var_len = 52341825Sdim ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx); 53341825Sdim for (idx = 0; (percent_var_idx = new_command.find( 54341825Sdim percent_var, idx)) != std::string::npos;) { 55341825Sdim new_command.erase(percent_var_idx, percent_var_len); 56341825Sdim new_command.insert(percent_var_idx, match_str); 57341825Sdim idx += percent_var_idx + match_str.size(); 58314564Sdim } 59254721Semaste } 60314564Sdim } 61341825Sdim // Interpret the new command and return this as the result! 62341825Sdim if (m_interpreter.GetExpandRegexAliases()) 63341825Sdim result.GetOutputStream().Printf("%s\n", new_command.c_str()); 64341825Sdim // Pass in true for "no context switching". The command that called us 65341825Sdim // should have set up the context appropriately, we shouldn't have to 66341825Sdim // redo that. 67341825Sdim return m_interpreter.HandleCommand( 68341825Sdim new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true); 69254721Semaste } 70314564Sdim } 71314564Sdim result.SetStatus(eReturnStatusFailed); 72341825Sdim if (!GetSyntax().empty()) 73341825Sdim result.AppendError(GetSyntax()); 74341825Sdim else 75341825Sdim result.GetOutputStream() << "Command contents '" << command 76341825Sdim << "' failed to match any " 77341825Sdim "regular expression in the '" 78341825Sdim << m_cmd_name << "' regex "; 79314564Sdim return false; 80254721Semaste} 81254721Semaste 82314564Sdimbool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr, 83314564Sdim const char *command_cstr) { 84314564Sdim m_entries.resize(m_entries.size() + 1); 85314564Sdim // Only add the regular expression if it compiles 86314564Sdim if (m_entries.back().regex.Compile( 87314564Sdim llvm::StringRef::withNullAsEmpty(re_cstr))) { 88314564Sdim m_entries.back().command.assign(command_cstr); 89314564Sdim return true; 90314564Sdim } 91314564Sdim // The regex didn't compile... 92314564Sdim m_entries.pop_back(); 93314564Sdim return false; 94254721Semaste} 95254721Semaste 96341825Sdimint CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) { 97314564Sdim if (m_completion_type_mask) { 98314564Sdim CommandCompletions::InvokeCommonCompletionCallbacks( 99341825Sdim GetCommandInterpreter(), m_completion_type_mask, request, nullptr); 100341825Sdim return request.GetNumberOfMatches(); 101314564Sdim } else { 102341825Sdim request.SetWordComplete(false); 103314564Sdim } 104314564Sdim return 0; 105254721Semaste} 106