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