1//===-- CommandObjectRegexCommand.cpp ---------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lldb/lldb-python.h" 11 12#include "lldb/Interpreter/CommandObjectRegexCommand.h" 13 14// C Includes 15// C++ Includes 16// Other libraries and framework includes 17// Project includes 18#include "lldb/Interpreter/CommandInterpreter.h" 19#include "lldb/Interpreter/CommandReturnObject.h" 20 21using namespace lldb; 22using namespace lldb_private; 23 24//---------------------------------------------------------------------- 25// CommandObjectRegexCommand constructor 26//---------------------------------------------------------------------- 27CommandObjectRegexCommand::CommandObjectRegexCommand 28( 29 CommandInterpreter &interpreter, 30 const char *name, 31 const char *help, 32 const char *syntax, 33 uint32_t max_matches, 34 uint32_t completion_type_mask 35) : 36 CommandObjectRaw (interpreter, name, help, syntax), 37 m_max_matches (max_matches), 38 m_completion_type_mask (completion_type_mask), 39 m_entries () 40{ 41} 42 43//---------------------------------------------------------------------- 44// Destructor 45//---------------------------------------------------------------------- 46CommandObjectRegexCommand::~CommandObjectRegexCommand() 47{ 48} 49 50 51bool 52CommandObjectRegexCommand::DoExecute 53( 54 const char *command, 55 CommandReturnObject &result 56) 57{ 58 if (command) 59 { 60 EntryCollection::const_iterator pos, end = m_entries.end(); 61 for (pos = m_entries.begin(); pos != end; ++pos) 62 { 63 RegularExpression::Match regex_match(m_max_matches); 64 65 if (pos->regex.Execute (command, ®ex_match)) 66 { 67 std::string new_command(pos->command); 68 std::string match_str; 69 char percent_var[8]; 70 size_t idx, percent_var_idx; 71 for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx) 72 { 73 if (regex_match.GetMatchAtIndex (command, match_idx, match_str)) 74 { 75 const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx); 76 for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; ) 77 { 78 new_command.erase(percent_var_idx, percent_var_len); 79 new_command.insert(percent_var_idx, match_str); 80 idx += percent_var_idx + match_str.size(); 81 } 82 } 83 } 84 // Interpret the new command and return this as the result! 85 if (m_interpreter.GetExpandRegexAliases()) 86 result.GetOutputStream().Printf("%s\n", new_command.c_str()); 87 // Pass in true for "no context switching". The command that called us should have set up the context 88 // appropriately, we shouldn't have to redo that. 89 return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result, NULL, true, true); 90 } 91 } 92 result.SetStatus(eReturnStatusFailed); 93 if (GetSyntax() != NULL) 94 result.AppendError (GetSyntax()); 95 else 96 result.AppendErrorWithFormat ("Command contents '%s' failed to match any regular expression in the '%s' regex command.\n", 97 command, 98 m_cmd_name.c_str()); 99 return false; 100 } 101 result.AppendError("empty command passed to regular expression command"); 102 result.SetStatus(eReturnStatusFailed); 103 return false; 104} 105 106 107bool 108CommandObjectRegexCommand::AddRegexCommand (const char *re_cstr, const char *command_cstr) 109{ 110 m_entries.resize(m_entries.size() + 1); 111 // Only add the regular expression if it compiles 112 if (m_entries.back().regex.Compile (re_cstr, REG_EXTENDED)) 113 { 114 m_entries.back().command.assign (command_cstr); 115 return true; 116 } 117 // The regex didn't compile... 118 m_entries.pop_back(); 119 return false; 120} 121 122int 123CommandObjectRegexCommand::HandleCompletion (Args &input, 124 int &cursor_index, 125 int &cursor_char_position, 126 int match_start_point, 127 int max_return_elements, 128 bool &word_complete, 129 StringList &matches) 130{ 131 if (m_completion_type_mask) 132 { 133 std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position); 134 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 135 m_completion_type_mask, 136 completion_str.c_str(), 137 match_start_point, 138 max_return_elements, 139 NULL, 140 word_complete, 141 matches); 142 return matches.GetSize(); 143 } 144 else 145 { 146 matches.Clear(); 147 word_complete = false; 148 } 149 return 0; 150} 151