]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Interpreter/CommandObjectRegexCommand.cpp
Vendor import of lldb trunk r338150:
[FreeBSD/FreeBSD.git] / source / Interpreter / CommandObjectRegexCommand.cpp
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/Interpreter/CommandObjectRegexCommand.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Interpreter/CommandInterpreter.h"
17 #include "lldb/Interpreter/CommandReturnObject.h"
18
19 using namespace lldb;
20 using namespace lldb_private;
21
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,
28     bool is_removable)
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) {}
32
33 //----------------------------------------------------------------------
34 // Destructor
35 //----------------------------------------------------------------------
36 CommandObjectRegexCommand::~CommandObjectRegexCommand() {}
37
38 bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
39                                           CommandReturnObject &result) {
40   EntryCollection::const_iterator pos, end = m_entries.end();
41   for (pos = m_entries.begin(); pos != end; ++pos) {
42     RegularExpression::Match regex_match(m_max_matches);
43
44     if (pos->regex.Execute(command, &regex_match)) {
45       std::string new_command(pos->command);
46       std::string match_str;
47       char percent_var[8];
48       size_t idx, percent_var_idx;
49       for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
50         if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) {
51           const int percent_var_len =
52               ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
53           for (idx = 0; (percent_var_idx = new_command.find(
54                              percent_var, idx)) != std::string::npos;) {
55             new_command.erase(percent_var_idx, percent_var_len);
56             new_command.insert(percent_var_idx, match_str);
57             idx += percent_var_idx + match_str.size();
58           }
59         }
60       }
61       // Interpret the new command and return this as the result!
62       if (m_interpreter.GetExpandRegexAliases())
63         result.GetOutputStream().Printf("%s\n", new_command.c_str());
64       // Pass in true for "no context switching".  The command that called us
65       // should have set up the context appropriately, we shouldn't have to
66       // redo that.
67       return m_interpreter.HandleCommand(
68           new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true);
69     }
70   }
71   result.SetStatus(eReturnStatusFailed);
72   if (!GetSyntax().empty())
73     result.AppendError(GetSyntax());
74   else
75     result.GetOutputStream() << "Command contents '" << command
76                              << "' failed to match any "
77                                 "regular expression in the '"
78                              << m_cmd_name << "' regex ";
79   return false;
80 }
81
82 bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
83                                                 const char *command_cstr) {
84   m_entries.resize(m_entries.size() + 1);
85   // Only add the regular expression if it compiles
86   if (m_entries.back().regex.Compile(
87           llvm::StringRef::withNullAsEmpty(re_cstr))) {
88     m_entries.back().command.assign(command_cstr);
89     return true;
90   }
91   // The regex didn't compile...
92   m_entries.pop_back();
93   return false;
94 }
95
96 int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
97   if (m_completion_type_mask) {
98     CommandCompletions::InvokeCommonCompletionCallbacks(
99         GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
100     return request.GetMatches().GetSize();
101   } else {
102     request.GetMatches().Clear();
103     request.SetWordComplete(false);
104   }
105   return 0;
106 }