]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp
MFV r336946: 9238 ZFS Spacemap Encoding V2
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / 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(const char *command,
39                                           CommandReturnObject &result) {
40   if (command) {
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);
44
45       if (pos->regex.Execute(command, &regex_match)) {
46         std::string new_command(pos->command);
47         std::string match_str;
48         char percent_var[8];
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();
59             }
60           }
61         }
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,
70                                            true, true);
71       }
72     }
73     result.SetStatus(eReturnStatusFailed);
74     if (!GetSyntax().empty())
75       result.AppendError(GetSyntax());
76     else
77       result.AppendErrorWithFormat("Command contents '%s' failed to match any "
78                                    "regular expression in the '%s' regex "
79                                    "command.\n",
80                                    command, m_cmd_name.c_str());
81     return false;
82   }
83   result.AppendError("empty command passed to regular expression command");
84   result.SetStatus(eReturnStatusFailed);
85   return false;
86 }
87
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);
95     return true;
96   }
97   // The regex didn't compile...
98   m_entries.pop_back();
99   return false;
100 }
101
102 int CommandObjectRegexCommand::HandleCompletion(Args &input, int &cursor_index,
103                                                 int &cursor_char_position,
104                                                 int match_start_point,
105                                                 int max_return_elements,
106                                                 bool &word_complete,
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,
114         matches);
115     return matches.GetSize();
116   } else {
117     matches.Clear();
118     word_complete = false;
119   }
120   return 0;
121 }