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 ) : 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 //---------------------------------------------------------------------- 46 CommandObjectRegexCommand::~CommandObjectRegexCommand() 47 { 48 } 49 50 51 bool 52 CommandObjectRegexCommand::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 107 bool 108 CommandObjectRegexCommand::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 122 int 123 CommandObjectRegexCommand::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