CommandObjectRegexCommand.cpp revision 314564
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 38314564Sdimbool CommandObjectRegexCommand::DoExecute(const char *command, 39314564Sdim CommandReturnObject &result) { 40314564Sdim if (command) { 41314564Sdim EntryCollection::const_iterator pos, end = m_entries.end(); 42314564Sdim for (pos = m_entries.begin(); pos != end; ++pos) { 43314564Sdim RegularExpression::Match regex_match(m_max_matches); 44254721Semaste 45314564Sdim if (pos->regex.Execute(command, ®ex_match)) { 46314564Sdim std::string new_command(pos->command); 47314564Sdim std::string match_str; 48314564Sdim char percent_var[8]; 49314564Sdim size_t idx, percent_var_idx; 50314564Sdim for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) { 51314564Sdim if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) { 52314564Sdim const int percent_var_len = 53314564Sdim ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx); 54314564Sdim for (idx = 0; (percent_var_idx = new_command.find( 55314564Sdim percent_var, idx)) != std::string::npos;) { 56314564Sdim new_command.erase(percent_var_idx, percent_var_len); 57314564Sdim new_command.insert(percent_var_idx, match_str); 58314564Sdim idx += percent_var_idx + match_str.size(); 59254721Semaste } 60314564Sdim } 61254721Semaste } 62314564Sdim // Interpret the new command and return this as the result! 63314564Sdim if (m_interpreter.GetExpandRegexAliases()) 64314564Sdim result.GetOutputStream().Printf("%s\n", new_command.c_str()); 65314564Sdim // Pass in true for "no context switching". The command that called us 66314564Sdim // should have set up the context 67314564Sdim // appropriately, we shouldn't have to redo that. 68314564Sdim return m_interpreter.HandleCommand(new_command.c_str(), 69314564Sdim eLazyBoolCalculate, result, nullptr, 70314564Sdim true, true); 71314564Sdim } 72254721Semaste } 73254721Semaste result.SetStatus(eReturnStatusFailed); 74314564Sdim if (!GetSyntax().empty()) 75314564Sdim result.AppendError(GetSyntax()); 76314564Sdim else 77314564Sdim result.AppendErrorWithFormat("Command contents '%s' failed to match any " 78314564Sdim "regular expression in the '%s' regex " 79314564Sdim "command.\n", 80314564Sdim command, m_cmd_name.c_str()); 81254721Semaste return false; 82314564Sdim } 83314564Sdim result.AppendError("empty command passed to regular expression command"); 84314564Sdim result.SetStatus(eReturnStatusFailed); 85314564Sdim return false; 86254721Semaste} 87254721Semaste 88314564Sdimbool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr, 89314564Sdim const char *command_cstr) { 90314564Sdim m_entries.resize(m_entries.size() + 1); 91314564Sdim // Only add the regular expression if it compiles 92314564Sdim if (m_entries.back().regex.Compile( 93314564Sdim llvm::StringRef::withNullAsEmpty(re_cstr))) { 94314564Sdim m_entries.back().command.assign(command_cstr); 95314564Sdim return true; 96314564Sdim } 97314564Sdim // The regex didn't compile... 98314564Sdim m_entries.pop_back(); 99314564Sdim return false; 100254721Semaste} 101254721Semaste 102314564Sdimint CommandObjectRegexCommand::HandleCompletion(Args &input, int &cursor_index, 103314564Sdim int &cursor_char_position, 104314564Sdim int match_start_point, 105314564Sdim int max_return_elements, 106314564Sdim bool &word_complete, 107314564Sdim StringList &matches) { 108314564Sdim if (m_completion_type_mask) { 109314564Sdim std::string completion_str(input.GetArgumentAtIndex(cursor_index), 110314564Sdim cursor_char_position); 111314564Sdim CommandCompletions::InvokeCommonCompletionCallbacks( 112314564Sdim GetCommandInterpreter(), m_completion_type_mask, completion_str.c_str(), 113314564Sdim match_start_point, max_return_elements, nullptr, word_complete, 114314564Sdim matches); 115314564Sdim return matches.GetSize(); 116314564Sdim } else { 117314564Sdim matches.Clear(); 118314564Sdim word_complete = false; 119314564Sdim } 120314564Sdim return 0; 121254721Semaste} 122