1 //===-- CommandObjectRegexCommand.cpp ---------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Interpreter/CommandObjectRegexCommand.h"
14 // Other libraries and framework includes
16 #include "lldb/Interpreter/CommandInterpreter.h"
17 #include "lldb/Interpreter/CommandReturnObject.h"
20 using namespace lldb_private;
22 //----------------------------------------------------------------------
23 // CommandObjectRegexCommand constructor
24 //----------------------------------------------------------------------
25 CommandObjectRegexCommand::CommandObjectRegexCommand(
26 CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help,
27 llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask,
29 : CommandObjectRaw(interpreter, name, help, syntax),
30 m_max_matches(max_matches), m_completion_type_mask(completion_type_mask),
31 m_entries(), m_is_removable(is_removable) {}
33 //----------------------------------------------------------------------
35 //----------------------------------------------------------------------
36 CommandObjectRegexCommand::~CommandObjectRegexCommand() {}
38 bool CommandObjectRegexCommand::DoExecute(const char *command,
39 CommandReturnObject &result) {
41 EntryCollection::const_iterator pos, end = m_entries.end();
42 for (pos = m_entries.begin(); pos != end; ++pos) {
43 RegularExpression::Match regex_match(m_max_matches);
45 if (pos->regex.Execute(command, ®ex_match)) {
46 std::string new_command(pos->command);
47 std::string match_str;
49 size_t idx, percent_var_idx;
50 for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
51 if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) {
52 const int percent_var_len =
53 ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
54 for (idx = 0; (percent_var_idx = new_command.find(
55 percent_var, idx)) != std::string::npos;) {
56 new_command.erase(percent_var_idx, percent_var_len);
57 new_command.insert(percent_var_idx, match_str);
58 idx += percent_var_idx + match_str.size();
62 // Interpret the new command and return this as the result!
63 if (m_interpreter.GetExpandRegexAliases())
64 result.GetOutputStream().Printf("%s\n", new_command.c_str());
65 // Pass in true for "no context switching". The command that called us
66 // should have set up the context
67 // appropriately, we shouldn't have to redo that.
68 return m_interpreter.HandleCommand(new_command.c_str(),
69 eLazyBoolCalculate, result, nullptr,
73 result.SetStatus(eReturnStatusFailed);
74 if (!GetSyntax().empty())
75 result.AppendError(GetSyntax());
77 result.AppendErrorWithFormat("Command contents '%s' failed to match any "
78 "regular expression in the '%s' regex "
80 command, m_cmd_name.c_str());
83 result.AppendError("empty command passed to regular expression command");
84 result.SetStatus(eReturnStatusFailed);
88 bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
89 const char *command_cstr) {
90 m_entries.resize(m_entries.size() + 1);
91 // Only add the regular expression if it compiles
92 if (m_entries.back().regex.Compile(
93 llvm::StringRef::withNullAsEmpty(re_cstr))) {
94 m_entries.back().command.assign(command_cstr);
97 // The regex didn't compile...
102 int CommandObjectRegexCommand::HandleCompletion(Args &input, int &cursor_index,
103 int &cursor_char_position,
104 int match_start_point,
105 int max_return_elements,
107 StringList &matches) {
108 if (m_completion_type_mask) {
109 std::string completion_str(input.GetArgumentAtIndex(cursor_index),
110 cursor_char_position);
111 CommandCompletions::InvokeCommonCompletionCallbacks(
112 GetCommandInterpreter(), m_completion_type_mask, completion_str.c_str(),
113 match_start_point, max_return_elements, nullptr, word_complete,
115 return matches.GetSize();
118 word_complete = false;